home *** CD-ROM | disk | FTP | other *** search
/ Varios Español / Varios Español.iso / DBASE5 / TEMPLATE.ZIP / REPORT.COD < prev    next >
Text File  |  1994-10-12  |  75KB  |  2,913 lines

  1. //
  2. // Module Name: REPORT.COD
  3. // Description: Define report program structure.
  4. //
  5. //
  6. Plantilla para Programas de Informes (.frg)
  7. -------------------------------------------
  8. Versión: 5.0
  9. Copyright (c) 1993,1994 Borland International, Inc.
  10. {
  11.  include "report.def";
  12.  include "builtin.def";
  13.  
  14.  if getenv("dtl_debug") then
  15.    debug(2)
  16.    breakpoint( pick_debug )
  17.  endif
  18.  
  19.  var  bnl_formname,     // Name of BNL file to newframe if argument() has value
  20.       arg_list;
  21.  
  22.  arg_list = argument()
  23.  if arg_list != "" then
  24.    bnl_formname = token( ",", arg_list, 1 )
  25.    if !newframe( bnl_formname ) then
  26.      return -1;
  27.    endif
  28.  endif
  29.  
  30. //
  31. // Enum string constants for international translation
  32. //
  33. enum
  34.     wrong_class = "Imposible usar REPORT.GEN con objetos que no sean informes.",
  35.     demo_string  = "MUESTRA DE INFORME DE dBASE 5.0 - SOLO PARA PROPOSITOS DE EVALUACION",
  36.     increase_page = "Aumente la longitud de página del informe.",
  37.     demo_version = 0;
  38.  
  39. enum    FIRST_GEN = 2;
  40.  
  41. enum    CHARACTER_TYPE = 67,
  42.         DATE_TYPE,
  43.         FLOAT_TYPE = 70,
  44.         LOGICAL_TYPE = 76,
  45.         MEMO_TYPE,
  46.         NUMERIC_TYPE = 78;
  47.  
  48. enum    AVERAGE_OP = 0,
  49.         COUNT_OP = 1,
  50.         MAX_OP,
  51.         MIN_OP,
  52.         SUM_OP,
  53.         STD_DEV_OP,
  54.         VARIANCE_OP;
  55.  
  56.     if frame_class != report then
  57.         pause(wrong_class + any_key)
  58.         return 0
  59.     endif
  60.  
  61. var
  62. // temporary variables
  63.     count,x,a,i,ni,j,k,temp,temp2,
  64. // global variables
  65.      rptname,   // Report name
  66.  default_drive, // dBASE default drive
  67.      isfirst,   // first system memvar? (handles commas)
  68.      isnew,     // is this a new band?
  69.      isopen,    // is the band open?
  70.      priv_vars, // system memvars list
  71.     priv_vars2, // if FLD_EXPRESSION is broken into 2 strings
  72.      bandedit,  // word wrap off or on
  73.      bandgrp,   // GROUP id for bands
  74.      bandhgt,   // band row position plus height plus one
  75.      bandlen2,  // length of page header (0 if band is closed)
  76.   bandspacing2, // spacing on page header band
  77.      bandlen50, // length of detail band        "
  78.    bandspacing, // spacing on detail band
  79.      bandlen98, // length of page footer        "
  80.  bandspacing98, // spacing on footer band
  81.      bandtype,  // type of band ie. page footer, report intro, etc.
  82.  band_previous, // previous bandtype
  83.      length,    // length of field or text
  84.      maxgrp,    // maximum number of bands
  85.      isrepo,    // is there report intro/summary bands
  86.      maxrow,    // maximum row
  87.      nextrow,   // next row when looking ahead ie. ++<cursor>
  88. current_column, // current text or field plus length
  89.      bsrv,      // beginning of band suppress repeated value
  90.      xsrv,      // current suppress repeated value var
  91.      xsum,      // current "noname" summary field
  92.      xxsum,     // subset of either an average, std. deviation or variance
  93.      samerow,   // flag set for items occuring on the same row
  94.      bandrow,   // band row plus one
  95.  first_combine, // text or field is the first in the chain of combined data
  96.      combine,   // combine fields flag
  97.  suppress_line, // if the text "Page no." appears first on the line
  98.   previous_row, // previous elements' row
  99.     pre_type,   // previous element type was field or text
  100.     next_type,
  101.    inner_loop,  // elements inside the band encountered
  102.   optl_heading, // flag to test whether optional heading has been output
  103. is_rintro_open, // is the Report Intro band open
  104.  is_rsumm_open, // is the Report Summary band open
  105. number_of_open_group_intros,   // none open, Grphead procedure is suppressed
  106. number_of_open_group_summarys, // none open, Grpfoot procedure is suppressed
  107. is_page_header_open, // if Page Header band is open
  108. number_of_reset_on_page, // summary fields reset on page
  109. number_of_fld_suppress,  // suppressed fields
  110. intro_band_one_height,   // footer widow checking for
  111. intro_band_two_height,   // dBASE III PLUS reports
  112. number_of_word_wrap_bands,
  113. number_of_group_calc_fields,
  114. number_of_group_footer_fields,
  115. number_of_group_intro_each,
  116. current_group_footer_field,
  117. number_of_begin_new_pages,
  118. retain_previous,
  119. external_define,
  120. blankable_row,
  121. left_delimiter,
  122. right_delimiter,
  123. delimit_flag,
  124. ruler_flag,
  125. previous_indent,
  126. previous_lmargin,
  127. previous_rmargin,
  128. previous_tabs,
  129. line_one_length
  130. ;
  131.     default_drive = STRSET(_defdrive)
  132.     rptname = FRAME_PATH + NAME
  133.     if not FILEOK(rptname) then
  134.         if FILEDRIVE(NAME) || !default_drive then
  135.             rptname=NAME
  136.         else
  137.             rptname=default_drive + ":" + NAME
  138.         endif
  139.     endif
  140.  
  141.     if not CREATE(rptname+".FRG") then
  142.         PAUSE(fileroot(rptname)+".FRG"+read_only+any_key)
  143.         return 0
  144.     endif
  145.  
  146.     pre_pass();
  147.  
  148. // variable initializations
  149.     bandrow=0
  150.     bsrv=0
  151.     combine=0
  152.     current_column=0
  153.     first_combine=1
  154.     isopen=0
  155.     maxrow=0
  156.     nextrow=0
  157.     optl_heading=0
  158.     previous_row=0
  159.     left_delimiter="\""
  160.     right_delimiter="\""
  161.     delimit_flag=0
  162.     samerow=0
  163.     xsrv=0
  164.     xsum=0
  165.     xxsum=0
  166.     isrepo=0
  167.     is_rintro_open=0
  168.     bandlen2=0
  169.     is_page_header_open=0
  170.     bandlen50=0
  171.     current_group_footer_field=0
  172.     number_of_begin_new_pages=0
  173.     number_of_group_footer_fields=0
  174.     number_of_group_intro_each=0
  175.     number_of_open_group_intros=0
  176.     number_of_open_group_summarys=0
  177.     number_of_word_wrap_bands=0
  178.     bandlen98=0
  179.     bandspacing=0
  180.     bandspacing98=0
  181.     is_rsumm_open=0
  182.     intro_band_one_height=0
  183.     intro_band_two_height=0
  184.     ruler_flag=1
  185.     line_one_length=0;  }
  186. * Programa...........: {rptname}.FRG
  187. * Fecha..............: {LTRIM(SUBSTR(DATE(),1,8))}
  188. * Versión............: dBASE {db_version_no}, Informes
  189. *
  190. * Notas:
  191. * ------
  192. * Antes de ejecutar este procedimiento con el mandato DO
  193. * es necesario usar LOCATE, pues la sentencia CONTINUE
  194. * está en el bucle principal.
  195. *
  196. *-- Parámetros
  197. PARAMETERS gl_noeject, gl_plain, gl_summary, gc_heading, gc_extra
  198. ** Los tres primeros parámetros son de tipo lógico.
  199. ** El cuarto es una serie y el quinto es un parámetro adicional.
  200. {
  201.     if dBASE_III_PLUS == FIRST_GEN then
  202.         a=", _plength, _ploffset";
  203.     else
  204.         a="";
  205.     endif
  206. }
  207. PRIVATE _peject{a}, _wrap, ll_heading, ll_temp, ll_toprint
  208. ll_heading = .F.
  209. ll_toprint = (SET("PRINTER") = "ON")
  210.  
  211. *-- Comprueba si no se ha encontrado ningún registro
  212. IF EOF() .OR. .NOT. FOUND()
  213.    RETURN
  214. ENDIF
  215.  
  216. *-- Desactiva la justificación entre márgenes.
  217. _wrap=.F.
  218.  
  219. {       report_setup();
  220. }
  221. IF _plength < {tb_margin(bandlen2,bandspacing2)} \
  222. + {tb_margin(bandlen98,bandspacing98)} + 2
  223.    SET DEVICE TO SCREEN
  224.    DEFINE WINDOW gw_report FROM 7,17 TO 11,62 DOUBLE
  225.    ACTIVATE WINDOW gw_report
  226.    @ 0,1 SAY "{increase_page}"
  227.    @ 2,1 SAY "{any_key}"
  228.    x=INKEY(0)
  229.    DEACTIVATE WINDOW gw_report
  230.    RELEASE WINDOW gw_report
  231.    RETURN
  232. ENDIF
  233.  
  234. _plineno=0          && pone el número de líneas a cero
  235. {   if dBASE_III_PLUS == FIRST_GEN then  }
  236.  
  237. *-- configuración de informe de dBASE III PLUS
  238. {
  239.     case PRINT_NEW_PAGE of
  240.     0: a="\"AFTER\""
  241.     1: a="\"BEFORE\""
  242.     2: a="\"BOTH\""
  243.     3: a="\"NONE\""
  244.     endcase
  245. }
  246. _peject={a}
  247. _plength={PRINT_PAGE_LENGTH}
  248. _ploffset={(!PRINT_LEFT_OFFSET) ? 0 : PRINT_LEFT_OFFSET}
  249.  
  250. *-- Opción PLAIN con destino a la pantalla solamente
  251. IF gl_plain
  252.    IF SET("PRINT") = "OFF" .AND. SET("ALTERNATE") = "OFF"
  253.       gl_noeject=.T.
  254.    ENDIF
  255. ENDIF
  256.  
  257. {   endif   }
  258. *-- Parámetro NOEJECT
  259. IF gl_noeject
  260.    IF _peject="BEFORE"
  261.       _peject="NONE"
  262.    ENDIF
  263.    IF _peject="BOTH"
  264.       _peject="AFTER"
  265.    ENDIF
  266. ENDIF
  267.  
  268. *-- Establecimiento de entorno
  269. ON ESCAPE DO Prnabort
  270. IF SET("TALK")="ON"
  271.    SET TALK OFF
  272.    gc_talk="ON"
  273. ELSE
  274.    gc_talk="OFF"
  275. ENDIF
  276. gc_space=SET("SPACE")
  277. SET SPACE OFF
  278. gc_time=TIME()      && Tiempo del sistema para el campo predefinido
  279. gd_date=DATE()      && Fecha del sistema  "    "    "     "
  280. gl_fandl=.F.        && indicador de primera y última página
  281. {       if number_of_group_intro_each then }
  282. gl_intros=.F.       && indicador para las introducciones de grupo para cada página
  283. {       endif   }
  284. gl_prntflg=.T.      && indicador de continuar impresión
  285. gl_widow=.T.        && indicador de comprobar apartados viudos
  286. gn_length=LEN(gc_heading)  && almacena la longitud del encabezamiento (HEADING)
  287. gn_level=2          && apartado actual en proceso
  288. gn_page=_pageno     && captura el número de página actual
  289. gn_pspace=_pspacing && captura el interlineado de la página impresa actual
  290.  
  291. {   init_group_footer_vars();
  292.     init_calculated_vars(); }
  293.  
  294. *-- Activa el procedimiento para el salto de página
  295. gn_atline=_plength - {tb_margin(bandlen98,bandspacing98)}
  296. ON PAGE AT LINE gn_atline EJECT PAGE
  297.  
  298. *-- Imprime el informe
  299.  
  300. PRINTJOB
  301.  
  302. {   if number_of_begin_new_pages then   }
  303. gl_newpage=.T.      && se puede comenzar apartado en página nueva
  304.  
  305. {   endif
  306.     init_group_break_vars()
  307.     init_summary_vars()
  308.     init_suppress_repeated_value_vars()
  309.     assign_calculated_vars()
  310.     assign_summary_vars()
  311.     if isrepo && is_rintro_open && not FRAME_PAGEHEADINGS then  }
  312. DO Rintro
  313.  
  314. *-- inicializa el núm.pág. por si la introducción del informe abarca 2 páginas
  315. _pageno=gn_page
  316.  
  317. {   endif   }
  318. IF gl_plain
  319.    ON PAGE AT LINE gn_atline DO Pgplain
  320. ELSE
  321.    ON PAGE AT LINE gn_atline DO Pgfoot
  322. ENDIF
  323.  
  324. {   if has_headers() then   }
  325. DO Pghead
  326.  
  327. {   endif   }
  328. gl_fandl=.T.        && comienzo de la primera página física
  329.  
  330. {   if isrepo && is_rintro_open && FRAME_PAGEHEADINGS then  }
  331. DO Rintro
  332. {       if number_of_begin_new_pages then   }
  333. gl_newpage=.F.
  334. {       endif  }
  335.  
  336. {   endif
  337.     if number_of_open_group_intros then }
  338. DO Grphead
  339. {       if number_of_group_intro_each then }
  340. gl_intros=.F.
  341. {       endif   }
  342.  
  343. {   endif   }
  344. *-- Bucle de fichero
  345. DO WHILE FOUND() .AND. .NOT. EOF() .AND. gl_prntflg
  346. {   lmarg(4)
  347. //
  348. // If there are group bands
  349. // set up the CASE structure to test
  350. // the group band values
  351. //
  352.     if (number_of_open_group_intros || number_of_open_group_summarys) then }
  353. DO CASE
  354. {       build_case_statement(); }
  355. OTHERWISE
  356.    gn_level=0
  357. ENDCASE
  358. *-- comprueba si alguna expresión no ha casado
  359. IF gn_level <> 0
  360. {       if number_of_open_group_summarys then   }
  361.    DO Grpfoot WITH 100-gn_level
  362. {       endif   }
  363.    DO Grpinit
  364. ENDIF
  365. {       if number_of_open_group_intros then }
  366. *-- Repite las introducciones de grupo
  367. IF gn_level <> 0
  368.    DO Grphead
  369. ENDIF
  370. {       endif
  371.         if number_of_group_intro_each then }
  372. gl_intros=.F.
  373. {       endif
  374.     endif   }
  375. gn_level=0
  376. {   if bandlen50 then   }
  377. *-- Cuerpo del informe
  378. IF gl_summary
  379.    DO Upd_Vars
  380. ELSE
  381.    DO __Detail
  382. ENDIF
  383. {   else    }
  384. DO Upd_Vars
  385. {   endif}
  386. gl_widow=.T.         && activa la comprobación de apartados viudos
  387. CONTINUE
  388. {   if number_of_open_group_intros || number_of_open_group_summarys then
  389.         increment_group_by_record_vars()
  390.     endif
  391.     lmarg(1);   }
  392. ENDDO
  393.  
  394. IF gl_prntflg
  395. //
  396. // If there are group bands
  397. //
  398. {   if maxgrp > 3 then  }
  399.    gn_level=3
  400. {       if number_of_open_group_summarys then   }
  401.    DO Grpfoot WITH 97
  402. {       endif
  403.     endif   }
  404. //
  405. // Report summary
  406. //
  407. {   if isrepo && is_rsumm_open then }
  408.    DO Rsumm
  409. {   endif
  410.     if bandlen98 then
  411.         if !is_rsumm_open then  }
  412.    gl_fandl=.F.     && fin de la última página
  413. {       endif   }
  414.    IF _plineno <= gn_atline
  415.       EJECT PAGE
  416.    ENDIF
  417. {   endif   }
  418. ELSE
  419. {   if isrepo && is_rsumm_open then
  420.         if maxgrp > 3 then  }
  421.    gn_level=3
  422. {       endif   }
  423.    DO Rsumm
  424. {   endif   }
  425.    DO Reset
  426.    RETURN
  427. ENDIF
  428.  
  429. ON PAGE
  430.  
  431. ENDPRINTJOB
  432.  
  433. DO Reset
  434. RETURN
  435. * EOP: {rptname}.FRG
  436. {   output_proc_gheight();  }
  437.  
  438. *-- Actualiza los campos resumen y/o los campos calculados.
  439. PROCEDURE Upd_Vars
  440. {   update_summary_and_calc_vars(); }
  441. RETURN
  442. * EOP: Upd_Vars
  443.  
  444. *-- Desactiva el indicador para salir del bucle DO WHILE cuando se pulse ESC
  445. PROCEDURE Prnabort
  446. gl_prntflg=.F.
  447. RETURN
  448. * EOP: Prnabort
  449.  
  450. {   if number_of_open_group_intros
  451.      || number_of_open_group_summarys then }
  452. *-- Reinicializa las variables de cambio de grupo, y los campos
  453. *-- resumen que vuelvan a empezar el cálculo cada apartado particular.
  454. PROCEDURE Grpinit
  455. {       reinit_group_variables(); }
  456. RETURN
  457. * EOP: Grpinit
  458.  
  459. {   endif
  460.     if number_of_reset_on_page || number_of_fld_suppress then   }
  461. *-- Vuelve a empezar el cálculo (cada página) de los campos resumen y suprime los valores repetidos
  462. PROCEDURE Pageinit
  463. {       reinit_page_variables(); }
  464. RETURN
  465. * EOP: Pageinit
  466.  
  467. {   endif
  468.     if (number_of_open_group_intros
  469.      || number_of_open_group_summarys) then
  470.         output_group_calls();
  471.     endif
  472.     if external_define then
  473.         fileerase(rptname+".grp");
  474.         APPEND(rptname+".FRG");
  475.     endif
  476.     output_band_procs();    }
  477.  
  478. *-- Proceso de los saltos de página cuando se usa la opción PLAIN
  479. PROCEDURE Pgplain
  480. PRIVATE _box
  481. EJECT PAGE
  482. {   if number_of_reset_on_page
  483.     || number_of_fld_suppress then  }
  484. IF gl_fandl
  485.    DO Pageinit
  486. ENDIF
  487. {   endif   }
  488. RETURN
  489. * EOP: Pgplain
  490.  
  491. *-- Restaura el entorno de dBASE previo a la impresión del informe
  492. PROCEDURE Reset
  493. SET SPACE &gc_space.
  494. SET TALK &gc_talk.
  495. ON ESCAPE
  496. ON PAGE
  497. RETURN
  498. * EOP: Reset
  499.  
  500. {
  501. return 0;
  502. //--------------------------------
  503. // End of main template procedure
  504. // User defined functions follow
  505. //--------------------------------
  506. define output_band_procs()
  507. //
  508. // Main loop which outputs the procedures for all the bands
  509. // and the contents of each band (also setup code).
  510. //
  511.     bandtype=99
  512. //
  513.     foreach ELEMENT ecursor
  514.         inner_loop=0
  515.         pre_type=0
  516.         next_type=0
  517. //
  518. // List type is a BAND?
  519. //
  520.         if ELEMENT_TYPE == @Band_Element then
  521.             begin_new_band(ecursor)
  522.             loop
  523.         else
  524.             ++count;
  525.         endif
  526.  
  527. do while ELEMENT_TYPE != @Band_Element && !eoc(ecursor)
  528.   inner_loop=1;
  529. //
  530.   if ELEMENT_TYPE == @Fld_Element then
  531.     if FLD_SUPPRESS then
  532.       ++xsrv;
  533.     endif
  534.  
  535.     retain_previous=0;
  536.     if GROUP > 50 then
  537.       retain_previous=retain_previous_value(ecursor)
  538.     endif
  539.     if retain_previous then
  540.       ++current_group_footer_field;
  541.     endif
  542.  
  543.     if !FLD_FIELDNAME && FLD_FIELDTYPE == Summ_data then
  544.       ++xsum;
  545.     endif
  546.   endif
  547. //
  548.   if FLD_HIDDEN || not isopen goto noprint endif
  549. //
  550. // Text or Field item begins on new row
  551. //
  552.   if ELEMENT_TYPE == @Text_Element || ELEMENT_TYPE == @Fld_Element then
  553.     if !pre_type || previous_row != Row_Positn then
  554.       samerow=0;
  555.       combine=0;
  556.       first_combine=1;
  557.     endif
  558.   endif
  559. //
  560.   if !optl_heading
  561.    && Row_Positn > bandrow+1
  562.    && bandtype == Page_Header then
  563.     if maxrow < bandrow+1 then }
  564. ?
  565.  
  566. {       ++maxrow;
  567.     endif   }
  568. *-- Parámetros para imprimir la cabecera - sin elementos en la primera línea
  569. IF .NOT. gl_plain
  570.    ?? gc_heading FUNCTION "I;V"+LTRIM(STR(_rmargin - _lmargin))
  571. ENDIF
  572.  
  573. {   optl_heading=1;
  574.   endif
  575. //
  576. // Output carriage returns for dBASE report
  577. //
  578.   if !bandedit then
  579. nextline1:
  580.     if maxrow < Row_Positn then }
  581. ?
  582. {     ++maxrow;
  583.       goto nextline1;
  584.     endif
  585.   else
  586.     if blankable_row && previous_row < Row_Positn then
  587.       blankable_row=0;
  588.       lmarg(1); }
  589. ENDIF
  590. {   endif
  591.     if (previous_row < Row_Positn) && (ELEMENT_TYPE == @Fld_Element
  592.     || ELEMENT_TYPE == @Text_Element) then
  593.       blankable_row=check4blank(ecursor);
  594.       if blankable_row then
  595.         if conditional_if_for_blank_line(ecursor) then
  596.           isnew=1;
  597.           lmarg(4);
  598.         endif
  599.       endif
  600.     endif
  601.     maxrow=Row_Positn;
  602.   endif
  603. //
  604. // Insert heading code for items on line one
  605. //
  606.     if line_one_length
  607.      && dBASE_III_PLUS != FIRST_GEN
  608.      && bandtype == Page_Header
  609.      && Row_Positn == bandrow+1 then    }
  610. *-- Parámetros para imprimir la cabecera - si no cabe en una línea
  611. *-- El valor añadido a gn_length es la última columna de la primera línea dos veces
  612. IF .NOT. gl_plain .AND. gn_length + {line_one_length * 2} > ln_width
  613.    ?? gc_heading FUNCTION "I;V"+LTRIM(STR(ln_width))
  614.    ?
  615.    ll_heading = .F.
  616. ENDIF
  617.  
  618. {       line_one_length=0;
  619.     endif
  620. //
  621.   pre_type=0;
  622.   next_type=0;
  623.   ++ecursor;
  624.   nextrow=Row_Positn;
  625.   if ELEMENT_TYPE == @Text_Element
  626.   || ELEMENT_TYPE == @Fld_Element then
  627.     next_type=1;
  628.   endif
  629.   --ecursor;
  630. //
  631.   case ELEMENT_TYPE of
  632.   @Text_Element:
  633. //
  634.     x=Col_Positn;
  635.     i=LEN(Text_Item);
  636.     ni=0;
  637.     pre_type=1;
  638.     if i == 237 then
  639.       foreach Text_Item fcursor in ecursor
  640.         if ni then
  641.           i=i+LEN(Text_Item);
  642.           temp=Text_Item;
  643.         endif
  644.         ++ni;
  645.       next
  646.     endif
  647.     current_column=x+i;
  648.     set_combine_flag(ecursor);
  649.     ++ecursor;
  650.     if (bandtype == Page_Header || bandtype == Page_Footer)
  651.       && ELEMENT_TYPE == @Fld_Element
  652.       && nextrow == maxrow then
  653.         if FLD_FIELDTYPE == Pred_data
  654.             && FLD_PREDEFINE == 3 then
  655.           --ecursor;
  656.           if SUBSTR(UPPER(Text_Item),1,4) == "PAGE" then
  657.             if previous_row == Row_Positn then
  658.                suppress_line=2;
  659.             else
  660.                suppress_line=1;
  661.             endif
  662.           endif
  663.           ++ecursor;
  664.           if suppress_line == 1 then
  665.             ++ecursor;
  666.             if !eoc(ecursor) && Row_Positn == nextrow then
  667.               suppress_line=2;
  668.             endif
  669.             --ecursor;
  670.           endif
  671.         endif
  672.     endif
  673.     --ecursor;
  674. //
  675.     if suppress_line == 1 &&
  676.      (bandtype == Page_Header || bandtype == Page_Footer) then
  677.        plainopt(ecursor);
  678.     endif
  679.     if isnew then
  680.       isnew=0;  }
  681. ?? \
  682. {   else
  683.       if samerow then}
  684.  \
  685. {     else}
  686. ?? \
  687. {     endif
  688.     endif
  689.     if substr(Text_Item,1,1) == "\"" then
  690.       left_delimiter = "["
  691.       right_delimiter = "]"
  692.       delimit_flag = 1
  693.     endif
  694.     if suppress_line == 2 then}
  695. IIF(gl_plain,'' , \
  696. {   endif
  697.     if i > 70 then}
  698. ;
  699. {     separate(Text_Item);
  700.       if ni then}
  701. + {left_delimiter}{temp}{right_delimiter};
  702. {     endif
  703.     else}
  704. {left_delimiter}{Text_Item}{right_delimiter} \
  705. {   endif
  706.     if suppress_line == 2 then}
  707. ) \
  708. {     suppress_line=0;
  709.     endif
  710.     if delimit_flag then
  711.       left_delimiter="\""
  712.       right_delimiter="\""
  713.       delimit_flag=0
  714.     endif
  715.   @Box_Element:}
  716. DEFINE BOX FROM {(!BOX_LEFT) ? 0 : BOX_LEFT} TO \
  717. {((!BOX_LEFT) ? 0 : BOX_LEFT)+BOX_WIDTH-1} \
  718. HEIGHT {BOX_HEIGHT} \
  719. {   case BOX_TYPE of
  720.     0: // Single}
  721. SINGLE
  722. {   1: // Double}
  723. DOUBLE
  724. {   2: // Defined}
  725. CHR({BOX_SPECIAL_CHAR})
  726. {   endcase
  727.   @Page_Element:}
  728. EJECT PAGE
  729. { @Para_Element:}
  730. ?
  731. { @Ruler_Element:
  732. //
  733.     ++ecursor;
  734.     if ELEMENT_TYPE == @Para_Element then
  735.       loop
  736.     endif
  737.     --ecursor;
  738.     a=((!RULER_LEFTM) ? 0 : RULER_LEFTM);
  739.     x=((!RULER_INDENT) ? 0 : RULER_INDENT);
  740.     if x && x > 255 then
  741.       x = x - 65536;
  742.     endif
  743.     i=0;
  744.     if ruler_flag || (a != previous_lmargin && x != previous_indent) then
  745.       if a + previous_indent < 0 then
  746.         if x >= 0 then   }
  747. _indent={x}
  748. {         i=1;
  749.         else    }
  750. _indent=0
  751. {       endif
  752.       endif     }
  753. _lmargin={a}
  754. {     if !i then    }
  755. _indent={x}
  756. {     endif
  757.       previous_indent=x;
  758.       previous_lmargin=a;
  759.     else
  760.       if x != previous_indent then  }
  761. _indent={x}
  762. {       previous_indent=x;
  763.       endif
  764.       if a != previous_lmargin then }
  765. _lmargin={a}
  766. {       previous_lmargin=a;
  767.       endif
  768.     endif
  769.     a=RULER_RIGHTM;
  770.     if ruler_flag || a != previous_rmargin then }
  771. _rmargin={a}
  772. {     previous_rmargin=a;
  773.     endif}
  774. _pcolno={previous_lmargin+x }
  775. {   a=RULER_TABS;
  776.     if ruler_flag || a != previous_tabs then    }
  777. _tabs=\
  778. {     if LEN(a) > 70 then}
  779. ;
  780. {       separate(a);}
  781.  
  782. {     else}
  783. "{a}"
  784. {     endif
  785.       previous_tabs=a;
  786.     endif
  787.     ruler_flag=0;
  788. }
  789. { @Fld_Element:
  790. //
  791.     x=Col_Positn;
  792.     i=FLD_REPWIDTH;
  793.     ni=0;
  794.     pre_type=1;
  795.     if i > 237 then
  796.       foreach FLD_TEMPLATE fcursor in ecursor
  797.         if ni then
  798.           temp2=FLD_TEMPLATE;
  799.         endif
  800.         ++ni;
  801.       next
  802.     endif
  803.     current_column=x+i;
  804. //
  805.     set_combine_flag(ecursor)
  806. //
  807.     k=0;
  808.     x=0;
  809.     priv_vars2="";
  810.     if dBASE_III_PLUS == FIRST_GEN && FLD_VALUE_TYPE == CHARACTER_TYPE &&
  811.     (FLD_FIELDTYPE == Tabl_data || FLD_FIELDTYPE == Calc_data) then
  812.       priv_vars="TRIM(";
  813.       x=1;
  814.     else
  815.       priv_vars="";
  816.     endif
  817.   if retain_previous then
  818.       priv_vars="r_foot"+str(current_group_footer_field);
  819.   else
  820.     case FLD_FIELDTYPE of
  821.     Tabl_data:
  822. // With ALIAS
  823. //      priv_vars=priv_vars+upper_first(FLD_FILENAME)+"->"+
  824. //                          upper_first(FLD_FIELDNAME);
  825. // Without ALIAS
  826.       priv_vars=priv_vars+upper_first(FLD_FIELDNAME);
  827.     Calc_data:
  828.       if FLD_FIELDNAME then
  829.         priv_vars=priv_vars+lower(FLD_FIELDNAME);
  830.       else
  831.         foreach FLD_EXPRESSION fcursor in ecursor
  832.           if k then
  833.             priv_vars2=FLD_EXPRESSION;
  834.           endif
  835.           ++k;
  836.         next
  837.         if (UPPER(SUBSTR(LTRIM(FLD_EXPRESSION),1,5))) != "TRIM(" then
  838.           priv_vars=priv_vars+FLD_EXPRESSION;
  839.         else
  840.           priv_vars=FLD_EXPRESSION;
  841.           x=0;
  842.         endif
  843.       endif
  844.     Pred_data: ;
  845.       case FLD_PREDEFINE of
  846.       0: // Date
  847.         priv_vars="gd_date";
  848.       1: // Time
  849.         priv_vars="gc_time";
  850.       2: // Recno
  851.         priv_vars="RECNO()";
  852.       3: // Pageno
  853.         priv_vars="_pageno";
  854.       endcase
  855.     Summ_data:
  856.       if !FLD_FIELDNAME then
  857.         priv_vars="r_msum"+STR(xsum);
  858.       else
  859.         priv_vars=lower(FLD_FIELDNAME);
  860.       endif
  861.     endcase
  862.   endif
  863.     if x then
  864.       priv_vars2=priv_vars2+")";
  865.     endif
  866.     if !suppress_line &&
  867.     (bandtype == Page_Header || bandtype == Page_Footer) then
  868.       plainopt(ecursor);
  869.     endif
  870. //
  871. // For output of suppress repeated value memo fields
  872. //
  873.     if FLD_SUPPRESS && FLD_VALUE_TYPE == MEMO_TYPE then  }
  874.  
  875. lf_temp={suppress_repeated_values(ecursor);}
  876. {     isnew=1;
  877.     endif
  878.     if isnew then
  879.       isnew=0;  }
  880. ?? \
  881. {   else
  882.       if samerow then}
  883.  \
  884. {     else}
  885. ?? \
  886. {     endif
  887.     endif
  888.     if FLD_SUPPRESS && FLD_VALUE_TYPE == MEMO_TYPE then  }
  889. &lf_temp. \
  890. {   else
  891.       suppress_repeated_values(ecursor);
  892.     endif
  893.  if Ok_Template(ecursor) then
  894.     j=0;
  895.     if FLD_PICFUN then
  896.       temp=FLD_PICFUN;
  897.       j=AT("V",temp) | AT("H",temp);
  898.       if not j then}
  899. FUNCTION "{FLD_PICFUN}" \
  900. {     else
  901.         if not AT("H",temp) then
  902.           if j < LEN(FLD_PICFUN) then
  903.             temp=SUBSTR(temp,1,j)+STR(i)+SUBSTR(temp,j+1);
  904.           else
  905.             temp=temp+STR(i);
  906.           endif
  907.         endif}
  908. FUNCTION "{temp}" \
  909. {     endif
  910.     endif
  911.     temp=FLD_TEMPLATE+temp2;
  912.     if FLD_VALUE_TYPE == CHARACTER_TYPE then
  913.       if FLD_LENGTH == FLD_REPWIDTH && temp == REPLICATE("X",FLD_LENGTH) then
  914.         j=FLD_LENGTH;
  915.       endif
  916.     endif
  917.     if not j then
  918. //
  919. // test for invalid picture templates
  920. //
  921.       if temp && (FLD_FIELDTYPE != Pred_data || FLD_PREDEFINE != 1) &&
  922.       FLD_VALUE_TYPE != DATE_TYPE then
  923.         if i > 70 then}
  924. PICTURE ;
  925. {         separate(temp);
  926.         else}
  927. PICTURE "{FLD_TEMPLATE}" \
  928. {       endif
  929.       endif
  930.     endif
  931.   endif    
  932.   endcase
  933. //
  934. // Style of output ie. BOLD, UNDERLINE and ITALICS.
  935. //
  936.   if FLD_STYLE then}
  937. STYLE "\
  938. {   if Bold & FLD_STYLE then}
  939. B\
  940. {   endif
  941.     if Italic & FLD_STYLE then}
  942. I\
  943. {   endif
  944.     if Underline & FLD_STYLE then}
  945. U\
  946. {   endif
  947.     if Superscript & FLD_STYLE then}
  948. R\
  949. {   endif
  950.     if Subscript & FLD_STYLE then}
  951. L\
  952. {   endif
  953.     if User_Font & FLD_STYLE then
  954.       if  1 & FLD_STYLE then}1{endif}\
  955. {     if  2 & FLD_STYLE then}2{endif}\
  956. {     if  4 & FLD_STYLE then}3{endif}\
  957. {     if  8 & FLD_STYLE then}4{endif}\
  958. {     if 16 & FLD_STYLE then}5{endif}\
  959. {   endif}
  960. " \
  961. { endif
  962. //
  963. // List type is TEXT or FIELD?
  964. //
  965.   if (ELEMENT_TYPE == @Text_Element || ELEMENT_TYPE == @Fld_Element) then
  966. //
  967. // not a word wrap band?
  968. //
  969.     if !bandedit && first_combine then  }
  970. AT {Col_Positn}\
  971. {   endif
  972.     if Row_Positn != nextrow then   }
  973.  
  974. {     isnew=1;
  975.     else
  976.       if FLD_SUPPRESS && bsrv != xsrv then    }
  977. ,
  978. {       isnew=1;
  979.       else
  980.         if next_type && Row_Positn == nextrow then
  981.           ++samerow;
  982.           if samerow > 7 then  // Break ?? command every 8 expressions}
  983. ,
  984. {           isnew=1;
  985.             samerow=1;
  986.           else    }
  987. ,;
  988. {         endif
  989.         else    }
  990.  
  991. {         isnew=1;
  992.         endif
  993.       endif
  994.     endif
  995. //
  996.     if FLD_SUPPRESS && bsrv != xsrv then
  997.         assign_suppress_var(ecursor);
  998.     endif
  999. //
  1000.     if first_combine && combine then
  1001.       first_combine=0;
  1002.     endif
  1003.     if !combine && !first_combine then
  1004.       first_combine=1;
  1005.     endif
  1006. //
  1007.   endif
  1008. //
  1009.   if !optl_heading && bandtype == Page_Header then
  1010.     if maxrow == bandrow+1 && nextrow > bandrow+1 then
  1011.         output_optional_heading()
  1012.     endif
  1013.   endif
  1014. //
  1015.   if bandtype == Page_Header || bandtype == Page_Footer then
  1016.     x=0;
  1017.     if previous_row < maxrow && nextrow > maxrow &&
  1018.     FLD_FIELDTYPE == Pred_data &&
  1019.     (!FLD_PREDEFINE || FLD_PREDEFINE == 3) then
  1020.       x=1;
  1021.     endif
  1022.     if x || (suppress_line && nextrow > maxrow) then
  1023.       if suppress_line && nextrow > maxrow then suppress_line=0; endif
  1024. //
  1025.       if optl_heading && nextrow > maxrow && bandtype != Page_Footer then}
  1026. ?
  1027. {       ++maxrow;
  1028.         isnew=1;
  1029.       endif
  1030.       lmarg(1);}
  1031. ENDIF
  1032. {   endif
  1033.   endif
  1034. noprint:
  1035.   x=0;
  1036.   if ELEMENT_TYPE != @Ruler_Element then
  1037.     previous_row=Row_Positn;
  1038.   endif
  1039.   ++ecursor;
  1040. enddo
  1041. if inner_loop then --ecursor; endif
  1042. next ecursor;
  1043. //
  1044. // Output carriage returns for dBASE report to handle blank lines
  1045. //
  1046. nextline3:
  1047. if maxrow < bandhgt then
  1048.   if isopen then}
  1049. ?
  1050. { endif
  1051.   ++maxrow;
  1052.   goto nextline3;
  1053. endif
  1054. if bandtype == Report_Summary && is_rsumm_open then
  1055. }
  1056. gl_fandl=.F.
  1057. ?
  1058. RETURN
  1059. * EOP: Rsumm
  1060. {
  1061. endif
  1062. if bandtype == Page_Footer then
  1063.   finish_page_footer();
  1064. endif
  1065. return;
  1066. enddef
  1067.  
  1068. define upper_first(string)
  1069.         // Takes and returns a string with first letter upper case
  1070.         return upper( substr( string,1,1)) + lower( substr( string,2))
  1071. enddef
  1072.  
  1073. define separate(string);
  1074. //
  1075. // Separates strings longer than 70 so that printed output
  1076. // of the report does not cause truncation or line wrap.
  1077. //
  1078.     var x,y,length;
  1079.     x=1
  1080.     length=LEN(string)
  1081. moreleft:
  1082.     if x <= length then
  1083.         if x != 1 then  }
  1084. + \
  1085. {       endif
  1086.         if x+70 <= length then
  1087.             y=70
  1088.         else
  1089.             y=length-x+1
  1090.         endif;  }
  1091. {left_delimiter}{SUBSTR(string,x,y)}{right_delimiter};
  1092. {       x=x+70
  1093.         goto moreleft;
  1094.     endif
  1095.     return
  1096. enddef
  1097.  
  1098. define retain_previous_value(cursor)
  1099. //
  1100. // Test whether a footer field needs to ...
  1101. //
  1102.     var result;
  1103.     result=0;
  1104.     case cursor.FLD_FIELDTYPE of
  1105.     Tabl_data: result=1
  1106.     Pred_data:
  1107.         if cursor.FLD_PREDEFINE == 2 then
  1108.             result=1
  1109.         endif
  1110.     endcase
  1111.     return result
  1112. enddef
  1113.  
  1114. define set_combine_flag(cursor)
  1115. //
  1116. // Determine whether field and or text are touching.
  1117. // If they are, a trim is performed on the field.
  1118. //
  1119.     ++cursor;
  1120.     if cursor.ELEMENT_TYPE == @Text_Element
  1121.      || cursor.ELEMENT_TYPE == @Fld_Element then
  1122.         if current_column == cursor.Col_Positn
  1123.          && maxrow == cursor.Row_Positn then
  1124.             combine=1;
  1125.         else
  1126.             combine=0;
  1127.         endif
  1128.     endif
  1129.     --cursor;
  1130. enddef
  1131.  
  1132. define assign_suppress_var(cursor)}
  1133. IF .NOT. (r_msrv{xsrv} = \
  1134. //
  1135. {     if !cursor.FLD_FIELDNAME then
  1136.         if cursor.FLD_FIELDTYPE == Calc_data then}
  1137. {extend(cursor,@FLD_EXPRESSION)}
  1138. {       endif
  1139.         if cursor.FLD_FIELDTYPE == Summ_data then}
  1140. r_msum{xsum}\
  1141. {       endif
  1142.       else
  1143.         if cursor.FLD_VALUE_TYPE == MEMO_TYPE then}
  1144. LEFT({upper_first(cursor.FLD_FIELDNAME)},254)\
  1145. {       else
  1146.           if cursor.FLD_FIELDTYPE == Tabl_data then
  1147. upper_first(cursor.FLD_FIELDNAME)}
  1148. {         else
  1149. lower(cursor.FLD_FIELDNAME)}
  1150. {         endif
  1151.         endif
  1152.       endif}
  1153. )
  1154. {     if !cursor.FLD_FIELDNAME then}
  1155.    r_msrv{xsrv}=\
  1156. {       if cursor.FLD_FIELDTYPE == Calc_data then}
  1157. {extend(cursor,@FLD_EXPRESSION)}
  1158.  
  1159. {       endif
  1160.         if cursor.FLD_FIELDTYPE == Summ_data then}
  1161. r_msum{xsum}
  1162. {       endif
  1163.       else}
  1164.    r_msrv{xsrv}=\
  1165. {       if cursor.FLD_FIELDTYPE == Tabl_data then
  1166. upper_first(cursor.FLD_FIELDNAME)}
  1167.  
  1168. {       else
  1169. lower(cursor.FLD_FIELDNAME)}
  1170.  
  1171. {       endif
  1172.       endif}
  1173. ENDIF
  1174. {
  1175.     return;
  1176. enddef
  1177.  
  1178. define suppress_repeated_values(cursor)
  1179. //
  1180. // Suppress repeated values
  1181. //
  1182.     if cursor.FLD_SUPPRESS then}
  1183. IIF(\
  1184. //
  1185. // Date field?
  1186. //
  1187. {       if cursor.FLD_VALUE_TYPE == DATE_TYPE then}
  1188. DTOS(r_msrv{xsrv}) \
  1189. {       else}
  1190. r_msrv{xsrv} \
  1191. {       endif}
  1192. <> \
  1193. //
  1194. // Date field?
  1195. //
  1196. {       if cursor.FLD_VALUE_TYPE == DATE_TYPE then}
  1197. DTOS({priv_vars}{priv_vars2})\
  1198. {       else}
  1199. //
  1200. // Memo field?
  1201. //
  1202. {           if cursor.FLD_VALUE_TYPE == MEMO_TYPE then}
  1203. LEFT({priv_vars},254)\
  1204. {           else}
  1205. {priv_vars}{priv_vars2}
  1206. {           endif}
  1207. {       endif}
  1208. //
  1209. // Memo field?
  1210. //
  1211. {       if cursor.FLD_VALUE_TYPE == MEMO_TYPE then}
  1212. ,[{priv_vars}],[""])
  1213. {       else}
  1214. ,{priv_vars}{priv_vars2},"") \
  1215. {       endif
  1216.     else
  1217.  priv_vars}{priv_vars2} \
  1218. {   endif
  1219. enddef
  1220.  
  1221. define extend(elk,selno)
  1222.     var result;
  1223.     foreach selno j in elk
  1224.         result = result + j.selno
  1225.     next j
  1226.     return result
  1227. enddef
  1228.  
  1229. define plainopt(cursor)
  1230. //
  1231. // Strictly for Page headers and Page footers, suppresses
  1232. // page numbers and dates when the PLAIN option is used.
  1233. //
  1234.     var temp; temp=0
  1235.     if previous_row < maxrow && nextrow > maxrow
  1236.      && cursor.FLD_FIELDTYPE == Pred_data
  1237.      && (!cursor.FLD_PREDEFINE || cursor.FLD_PREDEFINE == 3) then
  1238.         temp=1
  1239.     endif
  1240.     if temp || suppress_line then   }
  1241. IF .NOT. gl_plain
  1242. {       lmarg(4);
  1243.     else
  1244.         if cursor.FLD_FIELDTYPE == Pred_data &&
  1245.          (!cursor.FLD_PREDEFINE || cursor.FLD_PREDEFINE == 3) then
  1246.             if !cursor.FLD_PREDEFINE then
  1247.                 priv_vars="IIF(gl_plain,'',gd_date)"
  1248.             else
  1249.                 priv_vars="IIF(gl_plain,'',_pageno)"
  1250.             endif
  1251.         endif
  1252.     endif
  1253.     return
  1254. enddef
  1255.  
  1256. define output_optional_heading()
  1257. //
  1258. // Where to place the HEADING parameter in the page header
  1259. //
  1260. }
  1261.  
  1262. *-- Parámetros para imprimir la cabecera - si cabe en la primera línea
  1263. IF \
  1264. {if !suppress_line then}.NOT. gl_plain .AND. {endif}\
  1265. gn_length > 0 .AND. ll_heading
  1266.    ?? " "
  1267.    ?? gc_heading FUNCTION "I;V"+LTRIM(STR(ln_width-(_pcolno*2)))
  1268. ENDIF
  1269. {
  1270.     isnew=1;
  1271.     optl_heading=1;
  1272. enddef
  1273.  
  1274. define begin_new_band(cursor)
  1275. //
  1276. // Code output at the beginning of each band procedure
  1277. //
  1278.     band_previous=bandtype
  1279.     bandtype=cursor.BAND_BANDTYPE
  1280.     samerow=0
  1281.     combine=0
  1282.     first_combine=1
  1283.     ruler_flag=1;
  1284. //
  1285. // Output carriage returns for dBASE report to handle blank lines
  1286. //
  1287. nextline2:
  1288.     if maxrow < bandhgt then
  1289.         if isopen then  }
  1290. ?
  1291. {       endif
  1292.         ++maxrow;
  1293.         goto nextline2;
  1294.     endif
  1295.     if blankable_row then
  1296.         blankable_row=0;
  1297.         lmarg(1);   }
  1298. ENDIF
  1299. {   endif
  1300. //
  1301. // beyond the first band?
  1302. //
  1303.     if band_previous != 99 then
  1304. //
  1305.         if number_of_begin_new_pages && isopen then
  1306.             if band_previous == Group_Intro
  1307.              || band_previous == Detail
  1308.              || band_previous == Group_Summary then }
  1309. gl_newpage=.F.
  1310. {             if band_previous == Group_Intro ||
  1311.                  band_previous == Group_Summary then }
  1312. ?
  1313. {             endif
  1314.            endif
  1315.         endif
  1316.         if band_previous == Page_Header
  1317.          || band_previous == Page_Footer
  1318.          || isopen then
  1319.             case band_previous of
  1320.             Page_Header:
  1321.                 if suppress_line then
  1322.                     suppress_line=0
  1323.                     lmarg(1);   }
  1324. ENDIF
  1325. {               endif   }
  1326. //
  1327. {               if isopen
  1328.                  || (is_rintro_open && FRAME_PAGEHEADINGS)
  1329.                  || number_of_open_group_intros then    }
  1330. RETURN
  1331. * EOP: Pghead
  1332. {               endif
  1333.             Report_Intro:   }
  1334. RETURN
  1335. * EOP: Rintro
  1336. {           Group_Intro:    }
  1337. RETURN
  1338. {           Detail: }
  1339. RETURN
  1340. * EOP: __Detail
  1341. {           Group_Summary:
  1342.                 if dBASE_III_PLUS == FIRST_GEN then }
  1343. IF ln_level < 9{if cursor.GROUP == 96 then}6{else}7{endif}
  1344.    ?
  1345. ENDIF
  1346. {               endif   }
  1347. RETURN
  1348. {           Report_Summary: }
  1349. gl_fandl=.F.        && fin de la última página
  1350. ?
  1351. RETURN
  1352. * EOP: Rsumm
  1353. {           Page_Footer:
  1354.                 finish_page_footer();
  1355.             endcase
  1356.         endif   }
  1357.  
  1358. {   endif
  1359. //
  1360. // capture band attributes
  1361. // -----------------------
  1362. // bandrow and maxrow for row position
  1363. // bandedit for word wrap band
  1364. // isopen for band open or closed
  1365. //
  1366.     if cursor.Row_Positn then
  1367.         bandhgt=cursor.Row_Positn+cursor.BAND_HEIGHT+1
  1368.         bandrow=cursor.Row_Positn+1
  1369.         maxrow=cursor.Row_Positn+1
  1370.     else
  1371.         bandhgt=cursor.BAND_HEIGHT+1
  1372.         bandrow=1
  1373.         maxrow=1;
  1374.     endif
  1375.  
  1376.     bandedit=cursor.BAND_BANDEDIT
  1377.     bandgrp=cursor.GROUP
  1378.     bsrv=xsrv
  1379.     isnew=1
  1380.     isopen=cursor.BAND_OPENFLG;
  1381. //
  1382.     if cursor.BAND_BANDTYPE == Page_header
  1383.      || cursor.BAND_BANDTYPE == Page_Footer
  1384.      || cursor.BAND_OPENFLG then
  1385.         if cursor.BAND_BANDTYPE then   }
  1386. PROCEDURE \
  1387. {       else
  1388.             if cursor.BAND_OPENFLG
  1389.              || (is_rintro_open && FRAME_PAGEHEADINGS)
  1390.              || number_of_open_group_intros then    }
  1391. PROCEDURE \
  1392. {           endif
  1393.         endif
  1394.         case bandtype of
  1395.         Page_Header:
  1396.             if cursor.BAND_OPENFLG
  1397.              || (is_rintro_open && FRAME_PAGEHEADINGS)
  1398.              || number_of_open_group_intros then    }
  1399. Pghead
  1400. {               if line_one_length then }
  1401. PRIVATE ll_heading, ln_width
  1402. ll_heading = .T.
  1403. ln_width = _rmargin - _lmargin
  1404. {               endif
  1405.             endif
  1406.         Report_Intro:   }
  1407. Rintro
  1408. {       Group_Intro:    }
  1409. Head{cursor.GROUP}
  1410. {           if not cursor.BAND_INTROEACH then  }
  1411. IF gn_level=1
  1412.    RETURN
  1413. ENDIF
  1414. {           endif
  1415.             if dBASE_III_PLUS == FIRST_GEN && cursor.GROUP == 4
  1416.              && intro_band_one_height && intro_band_two_height then
  1417.                 ++bandhgt;
  1418.             else
  1419.                 if number_of_begin_new_pages && isopen then
  1420.                     --bandhgt;
  1421.                 endif
  1422.             endif
  1423.         Detail: }
  1424. __Detail
  1425. {       Group_Summary:  }
  1426. Foot{cursor.GROUP}
  1427. {           if dBASE_III_PLUS == FIRST_GEN then }
  1428. ln_lines=IIF(ln_level < 97, \
  1429. {               case cursor.GROUP of
  1430.                 96: }
  1431. {intro_band_one_height+intro_band_two_height+2}, \
  1432. {intro_band_one_height+intro_band_two_height+1})
  1433. {               95: }
  1434. {intro_band_two_height+2}, \
  1435. {intro_band_two_height+1})
  1436. {               endcase }
  1437. IF _plineno+ln_lines > gn_atline
  1438.    _plineno=gn_atline
  1439.    ?
  1440. ENDIF
  1441. {           else
  1442.                 if number_of_begin_new_pages && isopen then
  1443.                     --bandhgt;
  1444.                 endif
  1445.             endif
  1446.         Report_Summary: }
  1447. Rsumm
  1448. {           --bandhgt;
  1449.         Page_Footer:    }
  1450. Pgfoot
  1451. PRIVATE _box{if isopen}, _pspacing{endif}
  1452. gl_widow=.F.         && desactiva la comprobación de líneas viudas
  1453. {           if isopen then  }
  1454. _pspacing=1
  1455. ?
  1456. {           endif
  1457.             if bandhgt then --bandhgt endif
  1458.             if cursor.BAND_OPENFLG && cursor.BAND_HEIGHT then }
  1459. IF .NOT. gl_plain
  1460.    _pspacing=gn_pspace
  1461. {             lmarg(4);
  1462.             endif
  1463.         endcase
  1464.     endif
  1465. //
  1466. // is the band open?
  1467. // make system memvars PRIVATE
  1468. // only if the values change
  1469. //
  1470.     if isopen then
  1471. //
  1472. // BAND_NEWPAGE  - Begin band on new page:  No, Yes|
  1473. //
  1474.         if cursor.BAND_NEWPAGE then    }
  1475. IF .NOT. gl_newpage
  1476.    gl_newpage=.T.
  1477.    EJECT PAGE
  1478. ENDIF
  1479. {       endif
  1480. //
  1481. // BAND_TEXTPITCH - Text pitch for band:  Pica, Elite, Condensed, Default|
  1482. //
  1483.         if cursor.BAND_TEXTPITCH != 3 then }
  1484. IF SET("PRINT") = "ON" .AND. _ppitch <> {text_pitch(cursor.BAND_TEXTPITCH)}
  1485.    PRIVATE _ppitch
  1486.    _ppitch = {text_pitch(cursor.BAND_TEXTPITCH)}
  1487. ENDIF
  1488. {       endif
  1489. //
  1490. // BAND_QUALITY - Quality pitch for band:  Yes, No|
  1491. //
  1492.         if cursor.BAND_QUALITY < 2 then    }
  1493. IF SET("PRINT") = "ON" .AND. {if !cursor.BAND_QUALITY then}.NOT. {endif}_pquality
  1494.    PRIVATE _pquality
  1495.    _pquality = {if cursor.BAND_QUALITY then}.F.{else}.T.{endif}
  1496. ENDIF
  1497. {       endif
  1498. //
  1499. // BAND_SPACING - Default, single, double or triple
  1500. //
  1501.         if cursor.BAND_SPACING then    }
  1502. IF _pspacing <> {cursor.BAND_SPACING}
  1503.    PRIVATE _pspacing
  1504.    _pspacing={cursor.BAND_SPACING}
  1505. ENDIF
  1506. {       endif
  1507. //
  1508. // BAND_BANDEDIT - Wordwrap band:  Yes, No|
  1509. //
  1510.         if number_of_word_wrap_bands then
  1511.             if cursor.BAND_BANDEDIT then   }
  1512. PRIVATE _indent, _lmargin, _rmargin, _tabs
  1513. {           endif   }
  1514. IF {if cursor.BAND_BANDEDIT then}.NOT. {endif}_wrap
  1515.    PRIVATE _wrap
  1516.    _wrap = {if cursor.BAND_BANDEDIT then}.T.{else}.F.{endif}
  1517. ENDIF
  1518. {       endif
  1519. //
  1520.         ni="";
  1521.         if cursor.BAND_BANDTYPE == Detail then
  1522.             if cursor.BAND_HEIGHT then
  1523.                 if !bandspacing then
  1524.                     if cursor.BAND_HEIGHT > 1 then
  1525.                         ni=STR(cursor.BAND_HEIGHT)+" * gn_pspace";
  1526.                     else
  1527.                         ni="gn_pspace";
  1528.                     endif
  1529.                 else
  1530.                     if bandspacing > 1 then
  1531.                         ni=STR(cursor.BAND_HEIGHT * cursor.BAND_SPACING);
  1532.                     else
  1533.                         if cursor.BAND_HEIGHT > 1 then
  1534.                             ni=STR(cursor.BAND_HEIGHT);
  1535.                         endif
  1536.                     endif
  1537.                 endif
  1538.                 if ni then  }
  1539. IF {ni} < gn_atline - {tb_margin(bandlen2,bandspacing2)}
  1540.    IF gl_widow .AND. _plineno+{ni} > gn_atline + 1
  1541.       EJECT PAGE
  1542. {                      // kjn added number..open
  1543.                     if number_of_open_group_intros &&
  1544.                        number_of_group_intro_each then }
  1545.       gl_intros=.F.
  1546. {                   endif
  1547.                   lmarg(1);  }
  1548.    ENDIF
  1549. ENDIF
  1550. {               endif
  1551.             endif}
  1552. DO Upd_Vars
  1553. {           if number_of_begin_new_pages then   }
  1554. gl_newpage=.F.
  1555. {           endif
  1556.         endif
  1557.         if cursor.Row_Positn then previous_row=cursor.Row_Positn endif;
  1558.     endif
  1559.     return
  1560. enddef
  1561.  
  1562. define text_pitch(pitch_value)
  1563.     var result;
  1564.     case pitch_value of
  1565.     0: result="\"PICA\""
  1566.     1: result="\"ELITE\""
  1567.     2: result="\"CONDENSED\""
  1568.     3: result="\"DEFAULT\""
  1569.     endcase
  1570.     return result
  1571. enddef
  1572.  
  1573. define check4blank(incursor);
  1574. //
  1575. // This function determines whether or not a line is "blankable".
  1576. // A flag is set if the line contains text made up of only spaces
  1577. // or a numeric with a function Z which prints nothing for zero values
  1578. // or a character field.  It is only called for word wrap bands.
  1579. //
  1580.     var blank_line,fld_flag,j,k,previous_row,temp;
  1581.     k=incursor;
  1582.     blank_line=1;
  1583.     fld_flag=0;
  1584.     previous_row=k.Row_Positn;
  1585.  
  1586.     do while !eoc(k);
  1587.       if k.Row_Positn > previous_row then
  1588.         blank_line=fld_flag;
  1589.         exit;
  1590.       endif
  1591.       if blank_line then
  1592.         if k.FLD_VALUE_TYPE == 78 then
  1593.           if not AT("Z",k.FLD_PICFUN) then
  1594.             blank_line=0;
  1595.           else
  1596.             ++fld_flag;
  1597.           endif
  1598.         else
  1599.           if k.Text_Item then
  1600.             j=LEN(k.Text_Item);
  1601.             temp = k.Text_Item;
  1602.             if j == 237 then
  1603.               foreach Text_Item fcursor in k
  1604.                 j=j+LEN(fcursor.Text_Item);
  1605.                 temp = temp + fcursor.Text_Item;
  1606.               next
  1607.             endif
  1608.             if space(j) != temp then
  1609.               blank_line=0;
  1610.             endif
  1611.           else
  1612.             if k.ELEMENT_TYPE == @Fld_Element then
  1613.               if k.FLD_VALUE_TYPE != 67 then
  1614.                 blank_line=0;
  1615.               else
  1616.                 ++fld_flag;
  1617.               endif
  1618.             endif
  1619.           endif
  1620.         endif
  1621.       endif
  1622.       if !blank_line then
  1623.         exit;
  1624.       endif
  1625.       ++k;
  1626.     enddo
  1627.   return blank_line;
  1628. enddef
  1629.  
  1630. define conditional_if_for_blank_line(incursor);
  1631. //
  1632. // A dBASE IF statement is output for lines tested by check4blank()
  1633. // to test whether the printed line will contain only spaces.
  1634. //
  1635.     var field_flag, line_format, item_num, current_row, cursor2;
  1636.        cursor2=incursor;
  1637.        current_row=cursor2.Row_Positn;
  1638.        item_num=1;
  1639. }
  1640. *-- Prueba si línea en blanco
  1641. PRIVATE tot_length
  1642. tot_length=0
  1643. tot_length=tot_length+LEN(TRIM( \
  1644. {
  1645.        do while !eoc(cursor2) && cursor2.Row_Positn == current_row}
  1646. {        if cursor2.ELEMENT_TYPE == @Fld_element then
  1647.            if field_flag then   }\
  1648. )) \
  1649. {            if line_format then    }
  1650.  
  1651. tot_length=tot_length+\
  1652. {              item_num=1;
  1653.              else
  1654.                if ++item_num <= 16 then   }\
  1655. + ;
  1656. {              else }
  1657.  
  1658. tot_length=tot_length+\
  1659. {                item_num=1;
  1660.                endif
  1661.              endif  }
  1662. LEN(TRIM( \
  1663. {          else
  1664.              field_flag=1;
  1665.            endif
  1666.          endif
  1667.          if cursor2.FLD_VALUE_TYPE == 78 then}
  1668. TRANSFORM(\
  1669. {          line_format = putfld(cursor2);}
  1670. ,"\
  1671. {          if cursor2.FLD_PICFUN then}
  1672. @{cursor2.FLD_PICFUN} \
  1673. {          endif}
  1674. {cursor2.FLD_TEMPLATE}") \
  1675. {//
  1676.          else
  1677.            if cursor2.ELEMENT_TYPE == @Fld_element then
  1678.              line_format = putfld(cursor2);
  1679.            endif
  1680.          endif
  1681.          ++cursor2;
  1682.        enddo}
  1683. ))
  1684. IF tot_length > 0
  1685. {  return 1;
  1686. enddef
  1687.  
  1688. define putfld(cursor);
  1689. //
  1690. // Subfunction of conditional_if_for_blank_line(), this places
  1691. // the individual fields on the same line as the IF statement.
  1692. //
  1693.     var retval,value,value2;
  1694.     retval=0;
  1695.     value=cursor.FLD_FIELDTYPE;
  1696.     case value of
  1697.     Tabl_data:
  1698.         if cursor.FLD_VALUE_TYPE == 77 then }
  1699. MLINE({upper_first(cursor.FLD_FIELDNAME)},1)\
  1700. {       else    }
  1701. {upper_first(cursor.FLD_FIELDNAME)}\
  1702. {       endif
  1703.     Calc_data:  }
  1704. {       if cursor.FLD_FIELDNAME then    }
  1705. {lower(cursor.FLD_FIELDNAME)}\
  1706. {       else
  1707.             foreach FLD_EXPRESSION exp in cursor    }
  1708. {FLD_EXPRESSION}\
  1709. {           next    }
  1710.  ;
  1711. {         retval=1;
  1712.         endif   }
  1713. {   Pred_data:
  1714.         value2=cursor.FLD_PREDEFINE;
  1715.         case value2 of
  1716.         0: // Date  }
  1717. gd_date\
  1718. {       1: // Time  }
  1719. gc_time\
  1720. {       2: // Recno }
  1721. RECNO()\
  1722. {       3: // Pageno}
  1723. _pageno\
  1724. {       endcase }
  1725. {   endcase }
  1726.  \
  1727. {   return retval;
  1728. enddef
  1729.  
  1730. define output_group_calls()
  1731.  
  1732.         if number_of_open_group_intros then }
  1733. *-- Procesa la Introducción de los grupos al cambiar de grupo
  1734. PROCEDURE Grphead
  1735. IF EOF()
  1736.    RETURN
  1737. ENDIF
  1738. PRIVATE _pspacing
  1739. {           if bandspacing then }
  1740. _pspacing={bandspacing}
  1741. {           else    }
  1742. _pspacing=gn_pspace
  1743. {           endif   }
  1744. {       endif
  1745.         if dBASE_III_PLUS == FIRST_GEN
  1746.          && !number_of_open_group_summarys then   }
  1747. IF gn_level > 3
  1748.    ?
  1749. ENDIF
  1750. {       endif
  1751.         if number_of_open_group_intros then }
  1752. IF gn_level = 0
  1753.    gn_level=50
  1754. ENDIF
  1755. {       endif
  1756.         check4widows()
  1757.         if external_define then
  1758.             textopen(rptname+".grp")
  1759.         endif
  1760.         foreach BAND_ELEMENT k
  1761.             case BAND_BANDTYPE of
  1762.             Group_Intro:
  1763.                 if BAND_OPENFLG then    }
  1764. IF gn_level <= {GROUP}{if BAND_INTROEACH then} .OR. gl_intros{endif}
  1765.    DO Head{GROUP}
  1766. ENDIF
  1767. {               endif
  1768.             Detail:
  1769.                 if number_of_open_group_intros then }
  1770. gn_level=0
  1771. RETURN
  1772. * EOP: Grphead.PRG
  1773.  
  1774. {               endif
  1775.                 if number_of_open_group_summarys then   }
  1776. *-- Procesa el Apartado de Resumen de Grupos al cambiar de grupos
  1777. PROCEDURE Grpfoot
  1778. PARAMETER ln_level
  1779. {               endif
  1780.             Group_Summary:
  1781.                 if external_define then
  1782.                     textspos(0);
  1783.                     temp2=STR(GROUP)+": ";
  1784.                     if (temp = find_string(temp2) ) then }
  1785. IF ln_level >= {GROUP}
  1786. {                       lmarg(4);
  1787.     substr(temp,5)  }
  1788.  
  1789. {                       do while (temp = find_string(temp2) )    }
  1790. {   substr(temp,5)  }
  1791.  
  1792. {                       enddo
  1793.                         lmarg(0);   }
  1794. ENDIF
  1795. {                   endif
  1796.                 endif
  1797.                 if BAND_OPENFLG then    }
  1798. IF ln_level >= {GROUP}
  1799.    DO Foot{GROUP}
  1800. ENDIF
  1801. {               endif
  1802.             Page_Footer:
  1803.                 if number_of_open_group_summarys then   }
  1804. RETURN
  1805. * EOP: Grpfoot.PRG
  1806.  
  1807. {               endif
  1808.                 exit;
  1809.             endcase
  1810.         next k;
  1811.         if external_define then
  1812.             textclose()
  1813.         endif
  1814. enddef
  1815.  
  1816. define find_string(string)
  1817. //
  1818. // Assume the text file is open and rewound.  Matches are
  1819. // done on exact equality.  Returns entire string.
  1820. //
  1821.     var length,retval,temp; length=len(string); retval="";
  1822.  
  1823.     do while ( temp = textgetl() ) != EOF
  1824.         if string == substr(temp,1,length) then
  1825.             retval = temp;
  1826.             exit
  1827.         endif
  1828.     enddo
  1829.  
  1830.     return retval;
  1831. enddef
  1832.  
  1833. define check4widows()
  1834. //
  1835. // Check for possible widow band for group intros (includes detail length)
  1836. //
  1837.     foreach BAND_ELEMENT cursor
  1838.         if cursor.BAND_BANDTYPE == Group_Intro && cursor.BAND_OPENFLG then
  1839. //
  1840.             ni="";
  1841.             if !cursor.BAND_SPACING && !bandspacing then
  1842.                 ni=" * gn_pspace";
  1843.             else
  1844.                 if !cursor.BAND_SPACING && bandspacing > 1 then
  1845.                     ni=" * "+str(bandspacing);
  1846.                 else
  1847.                     if cursor.BAND_SPACING > 1 then
  1848.                         ni=" * "+str(cursor.BAND_SPACING);
  1849.                     endif
  1850.                 endif
  1851.             endif
  1852.             if cursor.BAND_HEIGHT > 1 then
  1853.                 a=str(cursor.BAND_HEIGHT)+ni+" ";
  1854.             else
  1855.                 if ni then
  1856.                     a=substr(ni,4)+" ";
  1857.                 else
  1858.                     a="";
  1859.                 endif
  1860.             endif   }
  1861. IF gn_level = {GROUP}
  1862. {           lmarg(4);
  1863.             if a then   }
  1864. IF {a} < gn_atline
  1865. {               lmarg(7);
  1866.             endif   }
  1867. IF (gl_widow .AND. _plineno+Gheight({cursor.GROUP}) > gn_atline + 1)\
  1868. {           if cursor.BAND_HEIGHT then}
  1869.  ;
  1870. .OR. (gl_widow .AND. _plineno+\
  1871. {               if cursor.BAND_HEIGHT > 1 then}
  1872. {cursor.BAND_HEIGHT}{ni}\
  1873. {               else
  1874.                     if !cursor.BAND_SPACING then
  1875.                         if ni then}
  1876. {SUBSTR(ni,4)}\
  1877. {                       else}
  1878. 1\
  1879. {                       endif
  1880.                     else}
  1881. {cursor.BAND_SPACING}\
  1882. {                   endif
  1883.                 endif}
  1884.  > gn_atline)
  1885. {           else}
  1886.  
  1887. {           endif}
  1888.    EJECT PAGE
  1889. ENDIF
  1890. {           if a then
  1891.                 lmarg(4);   }
  1892. ENDIF
  1893. {           endif
  1894.             lmarg(1);   }
  1895. ENDIF
  1896. {       endif
  1897.     next
  1898.     return
  1899. enddef
  1900.  
  1901. define reinit_page_variables()
  1902. //
  1903. // Summary fields set to Reset every page are assigned starting values.
  1904. //
  1905.     i=0
  1906.     x=0;
  1907.     foreach FLD_ELEMENT k
  1908.         if FLD_SUPPRESS then    }
  1909. r_msrv{++x}={init_not_value(k)}{logical_expression(k)}
  1910. {       endif
  1911.         if FLD_FIELDTYPE == Summ_data then
  1912.             if !FLD_FIELDNAME then
  1913.                 ++i
  1914.             endif
  1915.             if FLD_RESET == Each_Page then
  1916.                 if !FLD_FIELDNAME then
  1917.                     priv_vars="r_msum"+STR(i)
  1918.                 else
  1919.                     priv_vars=lower(FLD_FIELDNAME)
  1920.                 endif
  1921.                 sub_init_summary_vars(k)
  1922.             else
  1923.                 if FLD_OPERATION > SUM_OP then
  1924.                     xxsum = xxsum + 4
  1925.                 else
  1926.                     if FLD_OPERATION == AVERAGE_OP then
  1927.                         xxsum = xxsum + 2
  1928.                     endif
  1929.                 endif
  1930.             endif
  1931.         endif
  1932.     next k;
  1933.     xxsum=0
  1934.     return
  1935. enddef
  1936.  
  1937. define reinit_group_variables()
  1938. //
  1939. // Group break and summary fields are setup for next grouping.
  1940. //
  1941.     i=0
  1942.     x=0
  1943.     foreach FLD_ELEMENT k
  1944. //
  1945. // Summary field and reset on group?
  1946. //
  1947.         if FLD_FIELDTYPE == Summ_data then
  1948.             if !FLD_FIELDNAME then
  1949.                 ++x
  1950.             endif
  1951.             if FLD_RESET > Each_Group then
  1952.                 if i && i != FLD_RESET then
  1953.                     i=0
  1954.                     lmarg(1);   }
  1955. ENDIF
  1956. {               endif
  1957.                 if i != FLD_RESET then    }
  1958. IF gn_level <= {FLD_RESET}
  1959. {                   i=FLD_RESET
  1960.                     lmarg(4)
  1961.                 endif
  1962.                 if !FLD_FIELDNAME then
  1963.                     priv_vars="r_msum"+STR(x)
  1964.                 else
  1965.                     priv_vars=lower(FLD_FIELDNAME)
  1966.                 endif
  1967.                 sub_init_summary_vars(k)
  1968.             else
  1969.                 if FLD_OPERATION > SUM_OP then
  1970.                     xxsum = xxsum + 4
  1971.                 else
  1972.                     if FLD_OPERATION == AVERAGE_OP then
  1973.                         xxsum = xxsum + 2
  1974.                     endif
  1975.                 endif
  1976.             endif
  1977.         endif
  1978.     next k;
  1979.     xxsum=0
  1980.     if i then
  1981.         i=0
  1982.         lmarg(1);   }
  1983. ENDIF
  1984. {   endif
  1985.     foreach BAND_ELEMENT k
  1986.         if BAND_BANDTYPE == Group_Intro then    }
  1987. //
  1988. // Reset Group break vars on group intro bands
  1989. //
  1990. IF gn_level <= {GROUP}
  1991.    r_mvar{GROUP}={group_break_type(k)}
  1992. ENDIF
  1993. {       else
  1994.             if BAND_BANDTYPE > Group_Intro then
  1995.                 exit
  1996.             endif
  1997.         endif
  1998.     next k;
  1999.     return
  2000. enddef
  2001.  
  2002. define update_summary_and_calc_vars()
  2003. //
  2004. // This function is currently based on a calc all scenario.
  2005. // Which means all calculations happen in a left to right and
  2006. // top to bottom based on position in the report design surface.
  2007. //
  2008.     var temp;
  2009.     x=1
  2010.     xsum=0
  2011.     xxsum=0
  2012.     if external_define then
  2013.        textopen(rptname+".grp")
  2014.     endif
  2015.     foreach FLD_ELEMENT k
  2016.         case k.FLD_FIELDTYPE of
  2017. //
  2018. // Initialize named calculated fields for all bands
  2019. //
  2020.         Calc_data:
  2021.             if k.FLD_FIELDNAME && k.GROUP != 3 then}
  2022. {lower(k.FLD_FIELDNAME)}={
  2023.                 foreach FLD_EXPRESSION j in k
  2024.                     j.FLD_EXPRESSION}
  2025. {               next}
  2026.  
  2027. {           endif
  2028. //
  2029. // Summary fields
  2030. //
  2031.         Summ_data:
  2032.             if !FLD_FIELDNAME then
  2033.                 ++xsum
  2034.                 priv_vars="r_msum"+STR(xsum)
  2035.             else
  2036.                 priv_vars=lower(FLD_FIELDNAME);
  2037.             endif
  2038.             if external_define then
  2039.                 textspos(0);
  2040.                 if upd_find_string(priv_vars+"=") then
  2041.                     loop
  2042.                 endif
  2043.             endif
  2044.             case FLD_OPERATION of
  2045.             AVERAGE_OP: }
  2046. *-- Media
  2047. r_sum{++xxsum}=r_sum{xxsum}+1{tabto(40)}&& contador
  2048. r_sum{++xxsum}=r_sum{xxsum}+{FLD_SUMFIELD}{tabto(40)}&& suma
  2049. {priv_vars}=r_sum{xxsum}/r_sum{xxsum-1}{tabto(40)}&& media
  2050. {           COUNT_OP:   }
  2051. *-- Contador
  2052. {priv_vars}={priv_vars}+1
  2053. {           MAX_OP:     }
  2054. *-- Máximo
  2055. IF {FLD_SUMFIELD} > {priv_vars}
  2056.    {priv_vars}={FLD_SUMFIELD}
  2057. ENDIF
  2058. {           MIN_OP:     }
  2059. *-- Mínimo
  2060. IF {FLD_SUMFIELD} < {priv_vars}
  2061.    {priv_vars}={FLD_SUMFIELD}
  2062. ENDIF
  2063. {           SUM_OP:     }
  2064. *-- Suma
  2065. {priv_vars}={priv_vars}+{FLD_SUMFIELD}
  2066. {           otherwise: // STD or VAR
  2067.                 if FLD_OPERATION == STD_DEV_OP then  }
  2068. *-- Desviación estándar
  2069. {               else    }
  2070. *-- Varianza
  2071. {               endif   }
  2072. r_sum{++xxsum}=r_sum{xxsum}+{FLD_SUMFIELD}^2\
  2073. {tabto(40)}&& suma de cuadrados
  2074. r_sum{++xxsum}=r_sum{xxsum}+{FLD_SUMFIELD}\
  2075. {tabto(40)}&& suma
  2076. r_sum{++xxsum}=r_sum{xxsum}+1\
  2077. {tabto(40)}&& contador
  2078. r_sum{++xxsum}=r_sum{xxsum-2}/r_sum{xxsum-1}\
  2079. {tabto(40)}&& media
  2080. *-- varianza
  2081. {priv_vars}=\
  2082. (r_sum{xxsum-3}+r_sum{xxsum-1}*(r_sum{xxsum}^2);
  2083.    -(2*r_sum{xxsum}*r_sum{xxsum-2}))/r_sum{xxsum-1}
  2084. {               if FLD_OPERATION == STD_DEV_OP then  }
  2085. {priv_vars}=SQRT({priv_vars})\
  2086. {tabto(40)}&& desviación estándar
  2087. {               endif
  2088.             endcase;
  2089.         otherwise:
  2090. //
  2091. // footer fields
  2092. //
  2093. // When a group break occurs the record pointer is positioned
  2094. // on the next group.  Therefore, it is neccessary to capture
  2095. // the values of the previous record into temporary variables.
  2096. //
  2097.             if GROUP > 50 then
  2098.                 retain_previous=0;
  2099.                 case k.FLD_FIELDTYPE of
  2100.                 Tabl_data: retain_previous=1;
  2101.                 Pred_data:
  2102.                         if k.FLD_PREDEFINE == 2 then
  2103.                             retain_previous=1;
  2104.                         endif
  2105.                 endcase
  2106.                 if retain_previous then
  2107.                     case FLD_FIELDTYPE of
  2108.                     Tabl_data:
  2109.                         temp = substr(FLD_FIELDNAME,1,1) +
  2110.                             lower(substr(FLD_FIELDNAME,2))
  2111.                     Pred_data:
  2112.                         temp = "RECNO()"
  2113.                     endcase;}
  2114. r_foot{x}={temp}
  2115. {                   ++x;
  2116.                 endif
  2117.             endif
  2118.         endcase
  2119.     next k;
  2120.     if external_define then
  2121.        textclose()
  2122.     endif
  2123.     xsum=0
  2124.     xxsum=0
  2125.     return
  2126. enddef
  2127.  
  2128. define upd_find_string(string)
  2129. //
  2130. // Assume the text file is open and rewound.  Matches are
  2131. // done on exact equality.  Determines whether string is found.
  2132. //
  2133.     var length,retval,temp; length=len(string); retval="";
  2134.  
  2135.     do while ( temp = textgetl() ) != EOF
  2136.         if string == substr(temp,5,length) then
  2137.             retval = "1";
  2138.             exit
  2139.         endif
  2140.     enddo
  2141.  
  2142.     return retval;
  2143. enddef
  2144.  
  2145. define output_proc_gheight()
  2146.     x=0
  2147.     foreach BAND_ELEMENT k
  2148.         if BAND_BANDTYPE > Group_Intro then
  2149.             exit
  2150.         endif
  2151.         if BAND_BANDTYPE == Group_Intro && BAND_OPENFLG then
  2152.             if !x then  }
  2153.  
  2154. *-- Determina la altura de los Apartados de Grupo y de informe por si hay apartados viudos
  2155. FUNCTION Gheight
  2156. PARAMETER Group_Band
  2157. retval=0              && Valor devuelto
  2158. {           endif   }
  2159. IF Group_Band <= {GROUP}
  2160.    retval = retval +\
  2161. {           if BAND_HEIGHT > 1 then }
  2162.  {BAND_HEIGHT}\
  2163. {           endif
  2164.             if !BAND_SPACING && !bandspacing then
  2165.                 if BAND_HEIGHT > 1 then } *{endif}\
  2166.  gn_pspace
  2167. {           else
  2168.                 if !BAND_SPACING && bandspacing > 1 then
  2169.                     if BAND_HEIGHT > 1 then } *{endif}\
  2170.  {bandspacing}
  2171. {               else
  2172.                     if BAND_SPACING > 1 then
  2173.                         if BAND_HEIGHT > 1 then } *{endif}\
  2174.  {BAND_SPACING}
  2175. {                   else
  2176.                         if BAND_HEIGHT < 2 then }
  2177.  {BAND_HEIGHT}\
  2178. {                       endif   }
  2179.  
  2180. {                   endif
  2181.                 endif
  2182.             endif   }
  2183. ENDIF
  2184. {           ++x
  2185.         endif
  2186.     next k;
  2187.     if x then
  2188.         if bandlen50 then   }
  2189. *-- suma la altura del Apartado del cuerpo del informe
  2190. retval = retval + \
  2191. {           if !bandspacing then    }
  2192. {               if bandlen50 > 1 then   }
  2193. {bandlen50} * \
  2194. {               endif   }
  2195. gn_pspace
  2196. {           else
  2197.                 if bandspacing > 1 then }
  2198. {bandspacing*bandlen50}
  2199.  
  2200. {               else}
  2201. {bandlen50}
  2202.  
  2203. {               endif
  2204.             endif
  2205.         endif   }
  2206. RETURN retval
  2207. * EOP: Gheight
  2208. {   endif
  2209.     return
  2210. enddef
  2211.  
  2212. define increment_group_by_record_vars()
  2213.     foreach BAND_ELEMENT k
  2214.         if BAND_BANDTYPE == Group_Intro then
  2215. //
  2216. // increment any group by record count vars.
  2217. //
  2218.             if BAND_GROUP_REC then  }
  2219. r_mvar{GROUP}=r_mvar{GROUP}+1
  2220. {           endif
  2221.         else
  2222.             if BAND_BANDTYPE > Group_Intro then
  2223.                 exit
  2224.             endif
  2225.         endif
  2226.     next k;
  2227.     return
  2228. enddef
  2229.  
  2230. define tb_margin(bandhgt,bandspc)
  2231.     var retval;
  2232. // Band set to default spacing
  2233.     if !bandspc then
  2234.  
  2235. // Detail band set to default
  2236.         if !bandspacing then
  2237.  
  2238. // Band height greater than 1
  2239.             if bandhgt > 1 then
  2240.                 retval="(_pspacing * "+STR(bandhgt)+" + 1)"
  2241.             else
  2242.                 if bandhgt then
  2243.                     retval="(_pspacing + 1)"
  2244.                 else
  2245.                     retval=1
  2246.                 endif
  2247.             endif
  2248.  
  2249. // Detail band is not default
  2250.         else
  2251.             retval=bandspacing * bandhgt +1
  2252.         endif
  2253.  
  2254. // Band is not default
  2255.     else
  2256.         retval=bandspc * bandhgt +1
  2257.     endif
  2258.     return retval
  2259. enddef
  2260.  
  2261. define build_case_statement()
  2262.     foreach BAND_ELEMENT k
  2263.         if BAND_BANDTYPE == Group_Intro then
  2264. //
  2265. // Group by field
  2266. //
  2267.             if BAND_GFIELD then }
  2268. CASE \
  2269. {               if at(">",BAND_GFIELD) then // Check for ALIAS
  2270. substr(BAND_GFIELD,at(">",BAND_GFIELD)+1)   }
  2271. {               else
  2272. BAND_GFIELD }
  2273. {               endif   }
  2274.  <> r_mvar{GROUP}
  2275. {           endif
  2276. //
  2277. // Group by expression
  2278. //
  2279.             if BAND_EXPRESSION then }
  2280. CASE (\
  2281. {               foreach BAND_EXPRESSION fcursor in k
  2282. BAND_EXPRESSION }
  2283. {               next    }
  2284. ) <> r_mvar{GROUP}
  2285. {           endif
  2286. //
  2287. // Group by record count
  2288. //
  2289.             if BAND_GROUP_REC then  }
  2290. CASE r_mvar{GROUP} > {BAND_GROUP_REC}
  2291. {           endif   }
  2292.    gn_level={GROUP}
  2293. {       endif
  2294.     next k;
  2295.     return
  2296. enddef
  2297.  
  2298. define init_group_footer_vars()
  2299.     x=0
  2300.     if number_of_group_footer_fields then
  2301.         x=1;    }
  2302. *-- Inicializa las variables de los campos de pie de grupo
  2303. {       do while x <= number_of_group_footer_fields }
  2304. r_foot{x}=.F.
  2305. {           ++x;
  2306.         enddo   }
  2307.  
  2308. {   endif
  2309.     return
  2310. enddef
  2311.  
  2312. define init_calculated_vars()
  2313. //
  2314. // Initialize calculated fields.  This is neccesary since summary,
  2315. // calculated or group break variables might reference the field.
  2316. //
  2317.     x=0
  2318.     foreach FLD_ELEMENT k
  2319. //
  2320. // Reset Summary (on page) and Suppress repeated values
  2321. //
  2322.         if FLD_FIELDTYPE == Summ_data && FLD_RESET == 1 then
  2323.             ++number_of_reset_on_page
  2324.         endif
  2325.         if FLD_SUPPRESS then
  2326.             ++number_of_fld_suppress
  2327.         endif
  2328. //
  2329. // only if there is a fieldname assigned to the calculated field
  2330. //
  2331.         if FLD_FIELDTYPE == Calc_data && FLD_FIELDNAME then
  2332.             if !x then  }
  2333. *-- Inicializa variables calculadas.
  2334. {           endif
  2335. lower(FLD_FIELDNAME)}={get_init_val(FLD_VALUE_TYPE)}
  2336. {           ++x
  2337.         endif
  2338.     next k;
  2339.     return
  2340. enddef
  2341.  
  2342. define get_init_val(valtype)
  2343. //
  2344. // Called by init_calculated_vars()
  2345. //
  2346.     var result;
  2347.     case valtype of
  2348.     DATE_TYPE: result="CTOD(\"  /  /  \")"
  2349.     FLOAT_TYPE: result="FLOAT(0)"
  2350.     LOGICAL_TYPE: result=".F."
  2351.     NUMERIC_TYPE: result="0"
  2352.     otherwise: result="\"\""
  2353.     endcase
  2354.     return result
  2355. enddef
  2356.  
  2357. define init_group_break_vars()
  2358.     x=1  // to obtain number of group bands
  2359.     number_of_open_group_intros=0
  2360.  
  2361.     foreach BAND_ELEMENT k
  2362.         if BAND_BANDTYPE == Group_Intro then
  2363.             if x == 1 then  }
  2364. *-- Inicializa las variables del cambio de grupo
  2365. {           endif
  2366.             if BAND_OPENFLG then
  2367.                 ++number_of_open_group_intros
  2368.             endif;  }
  2369. //
  2370. r_mvar{GROUP}={group_break_type(k)}
  2371. {           ++x
  2372.         endif
  2373.         if BAND_BANDTYPE == Detail then
  2374.             exit
  2375.         endif
  2376.     next k;
  2377.     maxgrp=x+2
  2378.     if x > 1 then   }
  2379.  
  2380. {   endif
  2381.     return
  2382. enddef
  2383.  
  2384. define group_break_type(cursor)
  2385. //
  2386. // Depending on type of group break e.g. Expression, Field or Record count
  2387. // assign the beginning value to the group break variable.
  2388. //
  2389.     var result;
  2390.     case cursor.BAND_GROUPTYPE of
  2391.     1: // by field
  2392.         if at(">",cursor.BAND_GFIELD) then  // Check for ALIAS
  2393.             result = substr(cursor.BAND_GFIELD,at(">",cursor.BAND_GFIELD)+1)
  2394.         else
  2395.             result = cursor.BAND_GFIELD
  2396.         endif
  2397.     3: // by record count
  2398.         result = "1"
  2399.     otherwise: // by expression
  2400.         foreach BAND_EXPRESSION j in cursor
  2401.             result = result + j.BAND_EXPRESSION
  2402.         next
  2403.     endcase
  2404.     return result
  2405. enddef
  2406.  
  2407. define init_summary_vars()
  2408. //
  2409. // Initialize summary fields, similar to calculated fields, it is
  2410. // necessary to assign "unrelated" starting values to these fields.
  2411. //
  2412.     x=0
  2413.     foreach FLD_ELEMENT k
  2414.         if FLD_FIELDTYPE == Summ_data then
  2415.             if !x then  }
  2416. *-- Inicializa las variables del resumen.
  2417. {           endif
  2418.             ++x
  2419.             if !FLD_FIELDNAME then
  2420.                 ++xsum
  2421.                 priv_vars="r_msum"+STR(xsum)
  2422.             else
  2423.                 priv_vars=lower(FLD_FIELDNAME)
  2424.             endif
  2425.             sub_init_summary_vars(k)
  2426.         endif
  2427.     next k;
  2428.     xsum=0
  2429.     xxsum=0
  2430.     if x then  }
  2431.  
  2432. {   endif
  2433.     return
  2434. enddef
  2435.  
  2436. define sub_init_summary_vars(cursor)
  2437. //
  2438. // Called by init_summary_vars() and reinit_group/page_variables()
  2439. // Set summary variables to starting values for next grouping.
  2440. //
  2441.     if cursor.FLD_OPERATION > SUM_OP then   }
  2442. STORE 0 TO r_sum{++xxsum},r_sum{++xxsum},\
  2443. r_sum{++xxsum},r_sum{++xxsum},{priv_vars}
  2444. {   else
  2445.         case cursor.FLD_OPERATION of
  2446.         AVERAGE_OP: }
  2447. STORE 0 TO r_sum{++xxsum},r_sum{++xxsum},{priv_vars}
  2448. {       COUNT_OP:   }
  2449. {priv_vars}=0
  2450. {       otherwise: // Min, Max or Sum
  2451.             if cursor.FLD_OPERATION == MIN_OP ||
  2452.                cursor.FLD_OPERATION == MAX_OP then
  2453.                 // ptr 63167 added MAX_OP}
  2454. {priv_vars}={cursor.FLD_SUMFIELD}
  2455. {           else    }
  2456. {priv_vars}=0
  2457. {           endif
  2458.         endcase
  2459.     endif
  2460.     return
  2461. enddef
  2462.  
  2463. define init_suppress_repeated_value_vars()
  2464.     x=0  // to offset each suppress repeated value variable
  2465. //
  2466.     foreach FLD_ELEMENT k
  2467. //
  2468. // suppress repeated values?
  2469. //
  2470.         if FLD_SUPPRESS then
  2471.             if !x then  }
  2472. *-- Inicializa las variables de suprimir los valores repetidos.
  2473. {           endif   }
  2474. r_msrv{++x}={init_not_value(k)}{logical_expression(k)}
  2475. {       endif
  2476.     next k;
  2477.     if x then   }
  2478.  
  2479. {   endif
  2480.     return
  2481. enddef
  2482.  
  2483. define init_not_value(elk)
  2484. //
  2485. // Used assign a reverse value to suppress repeated value variables.
  2486. // Needed to print the first in the list of suppresed values.
  2487. //
  2488.     var result;
  2489.     case elk.FLD_VALUE_TYPE of
  2490.     DATE_TYPE: result ="CTOD(\"  /  /  \")"
  2491.     FLOAT_TYPE: result="FLOAT(0)"
  2492.     LOGICAL_TYPE: result=".NOT. "
  2493.     NUMERIC_TYPE: result="0"
  2494.     otherwise: result="\"\""
  2495.     endcase
  2496.     return result
  2497. enddef
  2498.  
  2499. define logical_expression(elk)
  2500. //
  2501. // If suppressed variable is of logical type the expression is returned
  2502. //
  2503.     var result;
  2504.     if elk.FLD_VALUE_TYPE != LOGICAL_TYPE then return "" endif
  2505.     if elk.FLD_FIELDNAME then
  2506.         if FLD_FIELDTYPE == Tabl_data then
  2507.             result=upper_first(elk.FLD_FIELDNAME)
  2508.         else
  2509.             result=lower(elk.FLD_FIELDNAME)
  2510.         endif
  2511.     else
  2512.         result=extend(elk,@FLD_EXPRESSION)
  2513.     endif
  2514.     return result
  2515. enddef
  2516.  
  2517. define assign_calculated_vars()
  2518. //
  2519. // Now the starting values for calculated fields are assigned.
  2520. // It could be a table, calculated or summary field (or any combination).
  2521. //
  2522.     x=0
  2523.     foreach FLD_ELEMENT k
  2524. //
  2525. // only if there is a fieldname assigned to the calculated field
  2526. //
  2527.         if FLD_FIELDTYPE == Calc_data && FLD_FIELDNAME then
  2528.             if !x then  }
  2529. *-- Asigna valores iniciales a las variables calculadas.
  2530. {           endif}
  2531. {lower(FLD_FIELDNAME)}={
  2532.                 foreach FLD_EXPRESSION j in k
  2533.                     j.FLD_EXPRESSION}
  2534. {               next}
  2535.  
  2536. {           ++x
  2537.         endif
  2538.     next k;
  2539.     if x then   }
  2540.  
  2541. {   endif
  2542.     return
  2543. enddef
  2544.  
  2545. define assign_summary_vars()
  2546. //
  2547. // This is synonymous with assign_calculated_vars.
  2548. //
  2549.     x=0
  2550.     foreach FLD_ELEMENT k
  2551.         if FLD_FIELDTYPE == Summ_data then
  2552.             if !FLD_FIELDNAME then
  2553.                 ++xsum
  2554.             endif
  2555.             if FLD_OPERATION == MAX_OP || FLD_OPERATION == MIN_OP then
  2556.                 if !x then  }
  2557. *-- Inicializa de nuevo las variables de máximo y mínimo
  2558. *-- por si están basadas en un campo calculado.
  2559. {               endif
  2560.                 ++x
  2561.                 if !FLD_FIELDNAME then
  2562.                     priv_vars="r_msum"+STR(xsum)
  2563.                 else
  2564.                     priv_vars=lower(FLD_FIELDNAME)
  2565.                 endif;  }
  2566. {priv_vars}={FLD_SUMFIELD}
  2567. {           endif
  2568.         endif
  2569.     next k;
  2570.     xsum=0
  2571.     if x then   }
  2572.  
  2573. {   endif
  2574.     return
  2575. enddef
  2576.  
  2577. define finish_page_footer()
  2578. //
  2579. // Complete the bottom portion of the Page Footer band
  2580. //
  2581.     if suppress_line then
  2582.         suppress_line=0
  2583.         lmarg(1);   }
  2584. ENDIF
  2585. {   endif
  2586.     if isopen && bandhgt+1 then
  2587.       lmarg(1);  }
  2588. ENDIF
  2589. {   endif
  2590.     if demo_version then    }
  2591. ? "{demo_string}" FUNCTION "IV"+LTRIM(STR(_rmargin-_lmargin))
  2592. {   endif   }
  2593. EJECT PAGE
  2594. {   if number_of_group_intro_each then }
  2595. gl_intros=.T.
  2596. {   endif   }
  2597. {   if number_of_begin_new_pages then   }
  2598. gl_newpage=.T.
  2599. {   endif   }
  2600. *-- comprueba si el número de página es mayor que el de la última página
  2601. IF _pageno > _pepage
  2602.    GOTO BOTTOM
  2603.    SKIP
  2604.    gn_level=0
  2605. ENDIF
  2606. {   if number_of_reset_on_page || number_of_fld_suppress then   }
  2607. IF gl_fandl
  2608.    DO Pageinit
  2609. ENDIF
  2610. {   endif
  2611.     if has_headers() then
  2612.         if bandspacing then
  2613.             temp = bandspacing
  2614.         else
  2615.             temp = "gn_pspace"
  2616.         endif;  }
  2617. IF .NOT. gl_plain .AND. gl_fandl
  2618.    _pspacing={temp}
  2619.    DO Pghead
  2620. {     if number_of_group_intro_each then }
  2621.    IF gl_intros .AND. gn_level = 0
  2622.      DO GrpHead
  2623.      gl_newpage = .F.
  2624.      gl_intros = .F.
  2625.    ENDIF
  2626. {     endif   }
  2627. ENDIF
  2628. {   endif   }
  2629. RETURN
  2630. * EOP: Pgfoot
  2631. {   return
  2632. enddef
  2633.  
  2634. define has_headers()
  2635.     if is_page_header_open
  2636.      || (is_rintro_open && FRAME_PAGEHEADINGS)
  2637.      || number_of_open_group_intros then
  2638.         return 1
  2639.     else
  2640.         return 0
  2641.     endif
  2642. enddef
  2643.  
  2644. define pre_pass()
  2645. //
  2646. // Two passes are made thru the fields.  The first pass outputs a
  2647. // list of calculated fields to be used for lookup.  The next pass
  2648. // examines the "field to summarize on" attribute of summary fields
  2649. // and makes a list of those which reference the calc. fields.
  2650. //
  2651.     var xsum,xxsum,subgroup;
  2652.     external_define=0
  2653.     xsum=0
  2654.     xxsum=0
  2655.     number_of_group_calc_fields=0;
  2656.  
  2657.     create(rptname+".ord");
  2658.  
  2659.     foreach FLD_ELEMENT k
  2660.         if k.FLD_FIELDNAME && k.FLD_FIELDTYPE == Calc_data
  2661.         && k.GROUP > 3 && k.GROUP != 50 && k.GROUP < 97 then }
  2662. {k.FLD_FIELDNAME} = {if k.GROUP > 50 then k.GROUP else 100-k.GROUP endif}
  2663. {           ++number_of_group_calc_fields;
  2664.         endif
  2665.     next
  2666.     if number_of_group_calc_fields then
  2667.         create(rptname+".grp");
  2668.         textopen(rptname+".ord");
  2669.  
  2670.         foreach FLD_ELEMENT k
  2671.             if k.FLD_FIELDTYPE == Summ_data then
  2672.                 textspos(0);
  2673.                 if not ( subgroup=
  2674.                   pre_pass_find_string(k.FLD_SUMFIELD+" = ") ) then
  2675.                     subgroup = 50;
  2676.                 endif
  2677.                 if k.FLD_FIELDNAME then
  2678.                     priv_vars=lower(k.FLD_FIELDNAME);
  2679.                 else
  2680.                     ++xsum
  2681.                     priv_vars="r_msum"+STR(xsum);
  2682.                 endif
  2683.                 if subgroup != 50 then
  2684.                     if !external_define then
  2685.                         external_define=1;
  2686.                     endif
  2687.                     pre_pass_summary_field(k,subgroup);
  2688.                 endif
  2689.             endif
  2690.         next
  2691.  
  2692.         textclose();
  2693.     endif
  2694.     append(rptname+".FRG");
  2695.     fileerase(rptname+".ord");
  2696.     if not external_define then
  2697.         fileerase(rptname+".grp");
  2698.     endif
  2699.     return;
  2700. enddef
  2701.  
  2702. define pre_pass_find_string(string)
  2703. //
  2704. // Assume the text file is open and rewound.  Matches are
  2705. // done on exact equality, returns the right portion of the string.
  2706. //
  2707.     var length,retval,temp; length=len(string); retval="";
  2708.  
  2709.     do while ( temp = textgetl() ) != EOF
  2710.         if string == substr(temp,1,length) then
  2711.             retval = substr(temp,length+1);
  2712.             exit
  2713.         endif
  2714.     enddo
  2715.  
  2716.     return retval;
  2717. enddef
  2718.  
  2719. define pre_pass_summary_field(cursor,subgroup)
  2720. //
  2721. // Output a statement for the summary calculation to be included later.
  2722. //
  2723.     case cursor.FLD_OPERATION of
  2724.     AVERAGE_OP: }
  2725. {subgroup}: *-- Media
  2726. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+1{tabto(40)}&& contador
  2727. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+{cursor.FLD_SUMFIELD}{tabto(40)}&& suma
  2728. {subgroup}: {priv_vars}=r_sum{xxsum}/r_sum{xxsum-1}{tabto(40)}&& media
  2729. {   COUNT_OP:   }
  2730. {subgroup}: *-- Contar
  2731. {subgroup}: {priv_vars}={priv_vars}+1
  2732. {   MAX_OP:     }
  2733. {subgroup}: *-- Máximo
  2734. {subgroup}: IF {cursor.FLD_SUMFIELD} > {priv_vars}
  2735. {subgroup}:    {priv_vars}={cursor.FLD_SUMFIELD}
  2736. {subgroup}: ENDIF
  2737. {   MIN_OP:     }
  2738. {subgroup}: *-- Mínimo
  2739. {subgroup}: IF {cursor.FLD_SUMFIELD} < {priv_vars}
  2740. {subgroup}:    {priv_vars}={cursor.FLD_SUMFIELD}
  2741. {subgroup}: ENDIF
  2742. {   SUM_OP:     }
  2743. {subgroup}: *-- Suma
  2744. {subgroup}: {priv_vars}={priv_vars}+{cursor.FLD_SUMFIELD}
  2745. {   otherwise: // STD or VAR
  2746.         if cursor.FLD_OPERATION == STD_DEV_OP then  }
  2747. {subgroup}: *-- Desviación estándar
  2748. {       else    }
  2749. {subgroup}: *-- Varianza
  2750. {       endif   }
  2751. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+{cursor.FLD_SUMFIELD}^2\
  2752. {tabto(40)}&& suma de cuadrados
  2753. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+{cursor.FLD_SUMFIELD}\
  2754. {tabto(40)}&& suma
  2755. {subgroup}: r_sum{++xxsum}=r_sum{xxsum}+1\
  2756. {tabto(40)}&& contador
  2757. {subgroup}: r_sum{++xxsum}=r_sum{xxsum-2}/r_sum{xxsum-1}\
  2758. {tabto(40)}&& media
  2759. {subgroup}: *-- varianza
  2760. {subgroup}: {priv_vars}=(r_sum{xxsum-3}+r_sum{xxsum-1}*(r_sum{xxsum}^2);
  2761. {subgroup}:    -(2*r_sum{xxsum}*r_sum{xxsum-2}))/r_sum{xxsum-1}
  2762. {       if cursor.FLD_OPERATION == STD_DEV_OP then  }
  2763. {subgroup}: {priv_vars}=SQRT({priv_vars})\
  2764. {tabto(40)}&& desviación estándar
  2765. {       endif
  2766.     endcase;
  2767. enddef
  2768.  
  2769. define report_setup()
  2770. var cursor, ntemp;
  2771.     foreach BAND_ELEMENT cursor
  2772.  
  2773.         if BAND_BANDEDIT then
  2774.             ++number_of_word_wrap_bands;
  2775.         endif
  2776.  
  2777.         if BAND_NEWPAGE then
  2778.             ++number_of_begin_new_pages;
  2779.         endif
  2780.  
  2781.         case BAND_BANDTYPE of
  2782.         Report_Intro:
  2783.             isrepo=1;
  2784.             if BAND_OPENFLG then
  2785.                 is_rintro_open = 1;
  2786.             endif
  2787.  
  2788.         Page_Header:
  2789.             if BAND_OPENFLG then
  2790.                 is_page_header_open = 1;
  2791.                 bandlen2=BAND_HEIGHT;
  2792.                 if BAND_SPACING then
  2793.                     bandspacing2=BAND_SPACING;
  2794.                 endif
  2795.             else
  2796.                 bandspacing2=1;
  2797.             endif
  2798.  
  2799.         Group_Intro:
  2800.             if dBASE_III_PLUS == FIRST_GEN then
  2801.                 if GROUP == 4 then
  2802.                     intro_band_one_height = BAND_HEIGHT;
  2803.                 endif
  2804.                 if GROUP == 5 then
  2805.                     intro_band_two_height = BAND_HEIGHT;
  2806.                 endif
  2807.             endif
  2808.             if BAND_INTROEACH then
  2809.                 ++number_of_group_intro_each;
  2810.             endif
  2811.  
  2812.         Detail:
  2813.             if BAND_OPENFLG then
  2814.                 bandlen50=BAND_HEIGHT;
  2815.             endif
  2816.             if BAND_SPACING then
  2817.                 bandspacing=BAND_SPACING;
  2818.             endif
  2819.  
  2820.         Group_Summary:
  2821.             if BAND_OPENFLG then
  2822.                 ++number_of_open_group_summarys;
  2823.             endif
  2824.  
  2825.         Page_Footer:
  2826.             if BAND_OPENFLG then
  2827.                 bandlen98=BAND_HEIGHT;
  2828.                 if BAND_SPACING then
  2829.                     bandspacing98=BAND_SPACING;
  2830.                 endif
  2831.             else
  2832.                 bandspacing98=1;
  2833.             endif
  2834.  
  2835.         Report_Summary:
  2836.             if BAND_OPENFLG then
  2837.                 is_rsumm_open = 1;
  2838.             endif
  2839.         endcase
  2840.     next
  2841.     if demo_version then
  2842.         ++bandlen98;
  2843.     endif
  2844.  
  2845.     if number_of_open_group_summarys || is_rsumm_open || bandlen98 then
  2846.         foreach FLD_ELEMENT cursor
  2847.             if GROUP > 50 then
  2848.                 retain_previous=0;
  2849.                 case cursor.FLD_FIELDTYPE of
  2850.                 Tabl_data: retain_previous=1;
  2851.                 Pred_data:
  2852.                         if cursor.FLD_PREDEFINE == 2 then
  2853.                             retain_previous=1;
  2854.                         endif
  2855.                 endcase
  2856.                 if retain_previous then
  2857.                     ++number_of_group_footer_fields;
  2858.                 endif
  2859.             endif
  2860.         next
  2861.     endif
  2862.     cursor = makec(@ELEMENT);
  2863.     ntemp = 1;
  2864.     do while ntemp
  2865.         if cursor.ELEMENT_TYPE == @Band_Element
  2866.          && cursor.BAND_BANDTYPE == Page_header then
  2867.             ntemp = 0;
  2868.         else
  2869.             ++cursor;
  2870.         endif
  2871.     enddo
  2872.     ntemp = ((!cursor.Row_Positn) ? 0 : cursor.Row_Positn)+2;
  2873.     ++cursor;
  2874.     do while cursor.Row_Positn <= ntemp
  2875.         if cursor.Row_Positn == ntemp then
  2876.             line_one_length = ((!cursor.Col_Positn) ? 0 : cursor.Col_Positn);
  2877.             case cursor.ELEMENT_TYPE of
  2878.             @Text_Element:
  2879.                 foreach Text_Item tcursor in cursor
  2880.                     line_one_length += len(Text_Item);
  2881.                 next
  2882.             @Fld_Element:
  2883.                 line_one_length += cursor.FLD_REPWIDTH;
  2884.             @Box_Element:
  2885.                 line_one_length +=
  2886.                  ((!cursor.BOX_LEFT) ? 0 : cursor.BOX_LEFT)
  2887.                  + cursor.BOX_WIDTH-1;
  2888.             endcase
  2889.         else
  2890.             exit
  2891.         endif
  2892.         ++cursor;
  2893.     enddo
  2894.     if line_one_length then
  2895.         ++line_one_length;
  2896.     endif
  2897.     return;
  2898. enddef
  2899.  
  2900. define ok_template(cur)
  2901.      if cur.FLD_TEMPLATE && !(chr(cur.FLD_VALUE_TYPE) == "D" ||
  2902.                               chr(cur.FLD_VALUE_TYPE) == "G" ||
  2903.                               chr(cur.FLD_VALUE_TYPE) == "B"
  2904.                   ) then
  2905.         return 1;
  2906.      else
  2907.         return 0;
  2908.      endif
  2909. enddef
  2910.  
  2911. // EOP: REPORT.COD
  2912.  
  2913.